Skip to content

Commit

Permalink
Convert blog to use Eleventy instead of Next.js
Browse files Browse the repository at this point in the history
This came from me staring at the Next.js 13/14 update and just not
wanting to do it 🙈 Our blog is hella basic, so Next.js was somewhat
overkill either way. I've been playing around with Eleventy recently
and wanted to try converting the blog to it.

Overall the dependency management should be much simpler now. There is
a downside in that it introduces a new framework, but I'd say 11ty is
pretty basic to work with and given that we don't actively develop
on the blog I'd say its an okay trade-off.
  • Loading branch information
lhansford committed Nov 15, 2023
1 parent 4caf9a1 commit 5b66444
Show file tree
Hide file tree
Showing 134 changed files with 6,377 additions and 3,955 deletions.
35 changes: 35 additions & 0 deletions .eleventy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const readingTime = require("eleventy-plugin-reading-time");
const { default: markdownItPrism } = require("markdown-it-prism");

module.exports = function (eleventyConfig) {
eleventyConfig.addPassthroughCopy("./index.css");

eleventyConfig.addShortcode("formatDate", function (dateString) {
return new Date(dateString).toLocaleDateString(undefined, { dateStyle: 'medium' });
});

eleventyConfig.addShortcode("excerpt", function (post) {
if (post.data.subtitle) {
return post.data.subtitle;
}

const strings = post.content.slice(0, 160).split(" ");
strings.pop();
return `${strings.join(" ")}…`;
});

eleventyConfig.addPlugin(readingTime);

eleventyConfig.addCollection("tags", function (collectionApi) {
return [
...new Set(
collectionApi
.getAll()
.map((item) => item.data?.postTags || [])
.flat()
),
];
});

eleventyConfig.amendLibrary("md", mdLib => mdLib.use(markdownItPrism));
};
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v3

- name: Install
run: yarn
run: npm ci

- name: Build
run: yarn build
run: npm run build
8 changes: 4 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ jobs:
- uses: actions/checkout@v3

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1
with:
aws-region: eu-west-1
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}

- name: Install
run: yarn
run: npm ci

- name: Build
run: yarn build && yarn export
run: npm run build

- name: Deploy
if: ${{ success() }}
run: |
echo "Deploying production to ${{ secrets.S3_OUTPUT_URL }} from Github environment"
echo "... uploading to ${{ secrets.S3_OUTPUT_URL }}"
aws s3 sync out ${{ secrets.S3_OUTPUT_URL }} --delete
aws s3 sync _site ${{ secrets.S3_OUTPUT_URL }} --delete
echo "... done"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ yarn-error.log*
.serverless_nextjs

.vscode

# 11ty
_site
1 change: 0 additions & 1 deletion @types/mdx-prism.d.ts

This file was deleted.

1 change: 0 additions & 1 deletion @types/remark-html.d.ts

This file was deleted.

13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ You can tag your post by adding a tags field to your post frontmatter:
---
title: Structuring an Elixir+Phoenix App
date: "2020-07-17T22:12:03.284Z"
author: brian-underwood
author: Brian Underwood
tags:
- Elixir
- Phoenix
Expand All @@ -66,20 +66,21 @@ tags:

### Adding iframes/embeds

We use a custom syntax for embedding iframes (e.g. Youtube videos, etc.):
You can use HTML for embedding iframes (e.g. Youtube videos, etc.):

```markdown

<!-- with a caption -->
?[Here's my video](https://www.youtube.com/embed/5qap5aO4i9A)
<figure>
<iframe src="https://www.youtube.com/embed/dtxPp9UOcIc" height="480" width="670" allowfullscreen="true" frameborder="0"></iframe>
<figcaption>Here's my video</figcaption>
</figure>

<!-- without a caption -->
?[](https://www.youtube.com/embed/5qap5aO4i9A)
<iframe src="https://www.youtube.com/embed/dtxPp9UOcIc" height="480" width="670" allowfullscreen="true" frameborder="0"></iframe>

```

Domains must be whitelisted in [lib/markdownToHtml.ts](lib/markdownToHtml.ts).

#### Embedding tweets

Twitter doesn't use iframes by default, but you can utilise [https://twitframe.com/](https://twitframe.com/)
Expand Down
40 changes: 40 additions & 0 deletions _data/authors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[
{
"name": "Klas Eskilson",
"avatar": "1_zSqaPz5bMJHwmyprRRmK0g.jpeg"
},
{
"name": "Brian Underwood",
"avatar": "brian.jpg"
},
{
"name": "Anton Kondratiuk",
"avatar": "anton.jpeg",
"shortDescription": "Android Engineer - Platform"
},
{
"name": "Emil Bogren",
"avatar": "emil.jpeg",
"shortDescription": "Engineering Manager - Social"
},
{
"name": "Gayan Witharana",
"avatar": "gayan.jpg",
"shortDescription": "Frontend Engineer in the Web-Discovery team"
},
{
"name": "Knut Holm",
"avatar": "knut.jpeg",
"shortDescription": "Engineering Manager and Frontend Developer"
},
{
"name": "Luke Hansford",
"avatar": "luke_smallest.jpg",
"shortDescription": "Engineering manager and full-stack web developer"
},
{
"name": "Pedro Mancheno",
"avatar": "1_PG2n91CBU1I42lTpwkgz_g.jpeg",
"shortDescription": "Software Engineer. Crafting beautiful code for the sake of my future self."
}
]
3 changes: 3 additions & 0 deletions _data/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"siteTitle": "Fishbrain Engineering Blog"
}
62 changes: 62 additions & 0 deletions _includes/authors.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
pagination:
data: authors
size: 1
alias: author
permalink: "authors/{{ author.name | slugify }}/"
eleventyComputed:
title: "{{ author.name }} | {{ meta.siteTitle }}"
layout: layout.njk
---
<article class="mb-32">
<div class="tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left">
<h1 class="text-5xl md:text-6xl lg:text-7xl font-bold tracking-tighter leading-tight md:leading-none text-center md:text-left">
{{ author.name }}
</h1>
{% if author.shortDescription %}
<p class="mt-6 text-lg">{{ author.shortDescription }}</p>
{% endif %}
</div>
<section className="grid grid-cols-1 row-gap-0 mb-32">
{% for post in collections.post | reverse %}
{% if post.data.author == author.name %}
<div class="border-b-2 pb-8 mb-10">
{% if post.data.imageSrc %}
<div class="mb-5">
<div class="sm:mx-0">
<a aria-label="{{ post.data.postTitle }}" href="/posts/{{ post.fileSlug }}">
<img src="/posts/{{ post.fileSlug }}/{{ post.data.imageSrc }}" alt="{{ post.data.imageAlt }}" class="shadow-small hover:shadow-medium transition-shadow duration-200 w-full"/>
</a>
</div>
</div>
{% endif %}
<h3 class="text-3xl mb-3 leading-snug">
<a class="hover:underline" href="/posts/{{ post.fileSlug }}">{{ post.data.postTitle }}</a>
</h3>
<div class="text-lg markdown">
{% excerpt post %}
</div>
<div class="text-md my-4">
<time datetime="{{ post.data.date }}">{% formatDate post.data.date %}</time> - {{ post.content | readingTime }} read
</div>
<div class="flex items-center">
{% for a in authors %}
{% if a.name == post.data.author %}
<a aria-label="{{post.data.author}}" href="/authors/{{post.data.author | slugify }}">
<img
src="/images/authors/{{a.avatar}}"
class="w-12 h-12 rounded-full mr-4"
alt="{{post.data.author}}"
/>
</a>
{% endif %}
{% endfor %}
<a class="text-xl font-bold hover:underline" href="/authors/{{post.data.author | slugify }}">
{{post.data.author}}
</a>
</div>
</div>
{% endif %}
{% endfor %}
</section>
</article>
44 changes: 44 additions & 0 deletions _includes/index.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
layout: layout.njk
---

<section class="grid grid-cols-1 row-gap-0 mb-32">
{% for post in collections.post | reverse %}
<div class="border-b-2 pb-8 mb-10">
{% if post.data.imageSrc %}
<div class="mb-5">
<div class="sm:mx-0">
<a aria-label="{{ post.data.postTitle }}" href="/posts/{{ post.fileSlug }}">
<img src="/posts/{{ post.fileSlug }}/{{ post.data.imageSrc }}" alt="{{ post.data.imageAlt }}" class="shadow-small hover:shadow-medium transition-shadow duration-200 w-full"/>
</a>
</div>
</div>
{% endif %}
<h3 class="text-3xl mb-3 leading-snug">
<a class="hover:underline" href="/posts/{{ post.fileSlug }}">{{ post.data.postTitle }}</a>
</h3>
<div class="text-lg markdown">
{% excerpt post %}
</div>
<div class="text-md my-4">
<time datetime="{{ post.data.date }}">{% formatDate post.data.date %}</time> - {{ post.content | readingTime }} read
</div>
<div class="flex items-center">
{% for a in authors %}
{% if a.name == post.data.author %}
<a aria-label="{{post.data.author}}" href="/authors/{{post.data.author | slugify }}">
<img
src="/images/authors/{{a.avatar}}"
class="w-12 h-12 rounded-full mr-4"
alt="{{post.data.author}}"
/>
</a>
{% endif %}
{% endfor %}
<a class="text-xl font-bold hover:underline" href="/authors/{{post.data.author | slugify }}">
{{post.data.author}}
</a>
</div>
</div>
{% endfor %}
</section>
49 changes: 49 additions & 0 deletions _includes/layout.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>

<link rel="shortcut icon" href="/favicon.ico"/>
<link rel="alternate" type="application/rss+xml" href="/feed.xml"/>
<meta name="description" content="We make an app for fishing, the world's most popular hobby."/>
<meta name="color-scheme" content="light dark">
{% if metaImage %}
<meta property="og:image" content="{{ metaImage }}"/>
{% endif %}

<link rel="stylesheet" href="{{ '/assets/css/index.css' | url }}">
<link href="https://unpkg.com/[email protected]/themes/prism-nord.css" rel="stylesheet"/>
</head>
<body>
<div class="min-h-screen">

<div class="container max-w-3xl mx-auto px-5">
<header class="flex items-center mt-8 mb-4">
<a href="/">
<img src="/app-icon.png" alt="Fishbrain" class="h-12 mr-2"/>
</a>
<a href="/" class="hover:underline">
{% if metaImage %}
<h1 class="text-2xl md:text-4xl font-bold tracking-tight md:tracking-tighter leading-tight mr-auto">{{ meta.siteTitle }}</h1>
{% else %}
<div class="text-2xl md:text-4xl font-bold tracking-tight md:tracking-tighter leading-tight mr-auto">{{ meta.siteTitle }}</div>
{% endif %}
</a>
<input id="dark-mode" class="dark-mode-checkbox visually-hidden" type="checkbox">
</header>
<hr/>
<div class="py-2 uppercase text-sm text-gray-500">
<a class="hover:underline" href="https://fishbrain.com">Get the app</a>
<span class="px-2">|</span>
<a class="hover:underline" href="https://careers.fishbrain.com/">Join the team</a>
</div>
<hr class="mb-8"/>
<main>
{{ content | safe }}
</main>
</div>
</div>
</body>
</html>
75 changes: 75 additions & 0 deletions _includes/postLayout.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
layout: layout.njk
eleventyComputed:
title: "{{ postTitle }} | {{ meta.siteTitle }}"
metaImage: "{{ imageSrc }}"
---
<article class="mb-32">
<div class="tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left">
<h1 class="text-5xl md:text-6xl lg:text-7xl font-bold tracking-tighter leading-tight md:leading-none text-center md:text-left">
{{ postTitle }}
</h1>
{% if subtitle %}
<p class="mt-6 text-lg">{{ subtitle }}</p>
{% endif %}
</div>
<div class="hidden md:block md:mb-12">
<div class="flex items-center">
{% for a in authors %}
{% if a.name == author %}
<a class="text-xl font-bold hover:underline" href="/authors/{{author | slugify }}" aria-label="{{author}}">
<img
src="/images/authors/{{a.avatar}}"
class="w-12 h-12 rounded-full mr-4"
alt="{{author}}"
/>
</a>
{% endif %}
{% endfor %}
<a class="text-xl font-bold hover:underline" href="/authors/{{author | slugify }}">
{{author}}
</a>
</div>
</div>
<div class="mb-8 md:mb-16 max-w-2xl mx-auto">
{% if imageSrc %}
<div class="sm:mx-0">
<a href="/posts/{{slug}}" aria-label="{{title}}">
<img src="{{ imageSrc }}" alt="{{ imageAlt }}"/>
</a>
</div>
{% endif %}
</div>
<div class="max-w-2xl mx-auto">
<div class="block md:hidden mb-6">
<div class="flex items-center">
{% for a in authors %}
{% if a.name == author %}
<a aria-label="{{author}}" href="/authors/{{author | slugify }}">
<img
src="/images/authors/{{a.avatar}}"
class="w-12 h-12 rounded-full mr-4"
alt="{{author}}"
/>
</a>
{% endif %}
{% endfor %}
<a class="text-xl font-bold hover:underline" href="/authors/{{author | slugify }}">
{{author}}
</a>
</div>
</div>
<div class="mb-6 text-lg">
<time datetime="{{ date }}">{% formatDate date %}</time> - {{ content | readingTime }} read
</div>
</div>
<PostBody content={post.content} tags={post.postTags}/>
<div class="max-w-2xl mx-auto markdown">
{{ content | safe }}
<section class="flex flex-wrap">
{% for tag in postTags %}
<a href="/tags/{{ tag | slugify }}" class="bg-gray-400 py-2 px-4 text-gray-900 mr-4 mb-4">{{ tag }}</a>
{% endfor %}
</section>
</div>
</article>
Loading

0 comments on commit 5b66444

Please sign in to comment.