How I eleventy
In 2025 I started using Eleventy (11ty) for building my personal website. 11ty fundamentally is a tool that takes in an input directory of files and ouputs them to a dist directory. The parsing of those files are controlled in a file called eleventy.config.js
. That's it! It's super extensible, and below are some cool things I do with 11ty.
How I organize my code
I structure my 11ty code as below
filesystem
├─ dist
├─ public
├─ eleventy.config.ts
├─src
├─ _components
├─ _includes
├─ layouts
I have a public folder containing any global information, I use the addPassthroughCopy
function to set this up
eleventyConfig.addPassthroughCopy({
[path.join(__dirname, 'public')]: 'public',
});
I place the rest of my code in src
, which is configured by the return statement in the config file
export default async function (eleventyConfig: UserConfig) {
// rest of my code
return {
dir: {
input: 'src',
output: 'dist',
},
};
}
My layouts are in the _includes
directory, this is a default directory used file imports
I have a _components
folder that contains reusable web-components, you can see the section Playing with WebC for more details
Playing with WebC
Web components are actually really sick, and 11ty has a plugin that lets you use them in your code. First I use the package @11ty/eleventy-plugin-webc
then do the following in my config file.
import pluginWebc from "@11ty/eleventy-plugin-webc";
export default async function (eleventyConfig: UserConfig) {
eleventyConfig.addPlugin(pluginWebc, {
// Glob to find no-import global components
// This path is relative to the project-root!
// The default value is shown:
components: "src/_components/**/*.webc",
});
}
Web components are a little different in 11ty, they are written in a .webc
file which can contain your standard html tags, css, and javascript. Then 11ty will bundle and process them up, so you don't need to do any custom javascript finagling for building web components in the documented way.
<div id="current-time">
[00:00:00]
</div>
<style>
#current-time {
font-size: 1.5em;
color: #333;
}
</style>
<script>
function getTime() {
const currentTime = document.getElementById('current-time');
const date = new Date();
const hours = Intl.NumberFormat('en-US', {minimumIntegerDigits: 2}).format(date.getHours());
const minutes = Intl.NumberFormat('en-US', {minimumIntegerDigits: 2}).format(date.getMinutes());
const seconds = Intl.NumberFormat('en-US', {minimumIntegerDigits: 2}).format(date.getSeconds());
currentTime.innerHTML = `[${hours}:${minutes}:${seconds}]`;
}
setInterval(() => {
getTime();
}, 1000);
getTime();
</script>
The code above I use to display the current time on my website, I save it as current-time-component.webc
in my _components
folder. I then import by just writing <current-time></current-time>
in other webc files. In njk files I have to use the renderTemplate function to render the web component.
{ % renderTemplate "webc" %}
<current-time></current-time>
{ % endrenderTemplate %}
The renderTemplate function is another 11ty plugin, it allows some mixed templating languages in your code.
import { EleventyRenderPlugin } from "@11ty/eleventy";
export default async function (eleventyConfig: UserConfig) {
eleventyConfig.addPlugin(EleventyRenderPlugin);
}