Graphic Design Web Design SEO Web Development HTML & CSS JavaScript WordPress Eleventy Innovation Portfolio My YouTube Channel Speedlify Presenting Multi Grid Navigation Sounds Affordable & Reliable Golden Ratio Optimizations X-height

Components with Nunjucks and 11ty

By: on Jan 25, 2023
Using if else statements with Nunjucks

Components are perceived by many to be the holy grail of web technologies. They definitely have there place and give us a way to create reusable features without having to duplicate code or even content. They are good for elements on your site that get reused across multiple pages like pre-footer sections, tabs, numbers list icons or the many other ways there are to present content.

On the topic of Components

This can be a bit of a nebulous topic and depending on who you talk to, you can get a myriad of perspectives. Going down the path of components takes serious planning and like any programmatic way of building there is all ways the risks of technical debt.

Nunjucks to the rescue

Nunjucks has a great feature called macro that you can use to create simple components. The Nunjucks macro creates reusable chunks of content. This is also a great way to get started with web components.

We'll build a start to finish component using 11ty as the builder, and Nunjucks for the templating language. Nunjucks is a robust light weight template engine that is easy to work with and has good documentation. It also goes very nicely with 11ty to help programmatically build out features.

Build the easiest full fledge component ever with 11ty and Nunjucks

First we'll create a project folder and initialize node.
npm init -y

With a new node project created we can add 11ty.
npm install @11ty/eleventy

Once 11ty is installed we'll add a start command to the package.json file.

"scripts": {
"start": "eleventy --serve",
"build": "eleventy"
},

Start Eleventy with the npm start command. Now that we have Eleventy running we're ready to go.

Simple display card component

This will be a more minimal setup just using a src folder with a _includes folder and a components folder. We'll build a basic card component that gets added to a .html or .md file. Here's what it will look like when we're finished.

Example

Using if else statements with Nunjucks

About the content of the card to help promote your website.
Link

I will be setting up the .eleventy.js file first by adding the standard module.exports. Set the directory to the default output by using the _site folder. For the entry point set the input to the src folder we created.

Then let 11ty know the templateFormats and set the markdownTemplateEngine: "njk" to parse the files before markdown renders the rest of the file. Also add passThroughFileCopy to let 11ty know were going to be using additional files that are not Eleventy templates.

module.exports = function(eleventyConfig) {
return {
dir: {
input: 'src',
output: '_site'
},
templateFormats: [
'html',
'md',
'njk'
],
passthroughFileCopy: true,
markdownTemplateEngine: "njk"
}
};
starter 11ty site

In the components folder create a file called card.njk then add the macro and expressions to that.

This is a typical 11ty folder structure where the index.md file is the homepage and everything in our _includes folder is like our theme files. Here we can create a head.njk, footer.njk and so on.

Then we would build out the site pages inside the src folder.

The macro uses params to pass in our parameters. It works like a function that takes in variables we can use to return our values.

{%- macro component(name, params) -%}
<div class="card">
<img src="{{ params.imageUrl }}" class="one-third">
<p class="two-thirds">{{ params.text }}<br> <a href="{{ params.link }}">Link</a></p>
</div>
{%- endmacro -%}

Now we can create our 11ty index.md file in the src folder. Before we can add the component we have to import the macro.

<!DOCTYPE html>
<html>
<head>
<title>Document</title>
</head>
<body>
{%- from "components/card.njk" import component -%}
{{ component('card', {
imageUrl: 'https://design2seo.com/assets/blog/11ty/nunjucks-if/nunjucks-if.jpg',
text: 'About the content of the card to help promote your website.',
link: '#'
}) }}

</body>
</html>

Now all we need to do is add the CSS to the .html or .md file.

<style type="text/css">
div.card {
box-shadow: 0 1px 6px 0 rgb(32 33 36 / 28%);
border: 1px solid #dfe1e5;
background: white;
border-radius: 8px;
padding: 21px;
display: flex;
gap: 2rem;
}
.card .one-third {
width: 40%;
}
.card .two-thirds {
width: 70%;
}
</style>

And that's it, we have a full fledged component that can be manage from one place and has dynamic content.

To continue building a site from here we would pass through the .css in the .eleventy.js file, then link it to a base.njk file and chain it to the post front matter.

I have a Build a blog with 11ty series that covers this process.

bonus*Chaining CSS to front matter

A more efficient way to include the CSS for the component is to make a component-card.css file in the _includes folder. Then in a base.njk file create an if statement to check if the page front matter exists.

{% if (componentCard) %}{% include "component-card.css" %}{% endif %}

In the .html or .md file front matter add the variable componentCard. I like to add the on tag just as a helpful indicator, but it is not needed.

---
componentCard: on
---

I also use this method for setting up different page layout options kind of like templates.

Conclusion

At the moment, I am not seeing an option to add specific CSS or JS to the component but will be keeping an eye out for this. That's ok, I prefer to manage my CSS and JS through the _includes folder and front matter anyway.

For me this is a great-simple way to build components in Eleventy. These reusable nuggets are awesome!

Resources