Lafuente

blog

11 Aug 2020

Web components and eleventy

· 11ty webcomponents

Web components and eleventy

If you want to have some dynamic content in your eleventy static website, a good option is to use Web Components, they play very well together.

I'm going to explain how I added a web component to my blog, in this example I'll use model-viewer component. This is the final result:

Astronaut by Poly, licensed under CC-BY.

First, make sure that you set the html option for markdownIt to true in your eleventy config file (usually .eleventy.js):

module.exports = function (eleventyConfig) {
let markdownIt = require("markdown-it");
let options = {
html: true,
};

eleventyConfig.setLibrary("md", markdownIt(options));
};

You also need to tell eleventy to copy the web components to your output directory. If you installed model-viewer with npm, you can copy it adding this to your .eleventy.js config file:

eleventyConfig.addPassthroughCopy({
"node_modules/@google/model-viewer/dist/model-viewer.min.js":
"js-modules/model-viewer.min.js",
});

But you also need to import the web components in your web pages. To do that, I'm taking advantage of eleventy's Front Matter Data and the Data Cascade. In the front matter I define the components I want to use, that way I can load different components per page:

---
title: Web components and eleventy
tags:
  - 11ty
  - webcomponents
modules:
  - "model-viewer.min.js"
---

The modules property (you can use another name) is a list with all the files I want to load in that page. You need to process that property when the template is rendered. I use JavaScript for my templates, plus lit-html-server, but you should be able to adapted the next snippet to any of the Template Languages supported by eleventy:

const { html, renderToString } = require("@popeindustries/lit-html-server");
module.exports = class BaseTemplate {
async render(data) {
return renderToString(
html`
${data.modules.map(
(file) =>
html`<script type="module" src="/js-modules/${file}"></script>`
)}

`

);
}
};

You can see the real file here: blog/base.11ty.js

And now you can just write the html directly on your markdown files:

<model-viewer
src="/models/Astronaut.glb"
alt="A 3D model of an astronaut"
auto-rotate
camera-controls
>
</model-viewer>

This makes pretty easy to embedded custom components in your markdown documents, making it similar to writing MDX.

← Home