|
| 1 | +--- |
| 2 | +{ |
| 3 | + title: 'Eleventy', |
| 4 | + description: 'Use NVIDIA Elements in Eleventy with Vite-bundled component definitions and styles, template markup, and optional Lit server-side rendering.', |
| 5 | + layout: 'docs.11ty.js' |
| 6 | +} |
| 7 | +--- |
| 8 | + |
| 9 | +# {{ title }} |
| 10 | + |
| 11 | +{% integration 'eleventy' %} |
| 12 | + |
| 13 | +{% installation 'eleventy' %} |
| 14 | + |
| 15 | +Elements are standard Web Components, so Eleventy can emit their tags from any template language. For most sites, render the element markup at build time and register the components in the browser. Use Lit server-side rendering (SSR) only when component shadow DOM must be present in the generated HTML. |
| 16 | + |
| 17 | +## Client-Side Rendering |
| 18 | + |
| 19 | +The [Eleventy starter]({{ELEMENTS_REPO_BASE_URL}}/tree/main/projects/starters/eleventy) uses [Eleventy Plugin Vite](https://github.com/11ty/eleventy-plugin-vite) to bundle Elements styles and component definitions. This approach supports tree-shaking and keeps the Eleventy build environment separate from browser component registration. |
| 20 | + |
| 21 | +Install the Vite integration in an existing Eleventy project: |
| 22 | + |
| 23 | +```shell |
| 24 | +npm install --save-dev @11ty/eleventy-plugin-vite vite |
| 25 | +``` |
| 26 | + |
| 27 | +### Configure Eleventy and Vite |
| 28 | + |
| 29 | +Register the Vite plugin and copy the browser entry files into Eleventy's output for Vite to process: |
| 30 | + |
| 31 | +```javascript |
| 32 | +// eleventy.config.js |
| 33 | +import EleventyPluginVite from '@11ty/eleventy-plugin-vite'; |
| 34 | + |
| 35 | +export default function (eleventyConfig) { |
| 36 | + eleventyConfig.addPassthroughCopy('src/**/*.ts'); |
| 37 | + eleventyConfig.addPassthroughCopy('src/**/*.css'); |
| 38 | + |
| 39 | + eleventyConfig.addPlugin(EleventyPluginVite, { |
| 40 | + viteOptions: { |
| 41 | + build: { |
| 42 | + target: 'esnext' |
| 43 | + } |
| 44 | + } |
| 45 | + }); |
| 46 | + |
| 47 | + return { |
| 48 | + dir: { |
| 49 | + input: 'src', |
| 50 | + output: 'dist', |
| 51 | + layouts: '_layouts' |
| 52 | + } |
| 53 | + }; |
| 54 | +} |
| 55 | +``` |
| 56 | + |
| 57 | +If you deploy the site below the domain root, set the same base path in the Vite `base` option and the document's `<base>` element. Keeping those values aligned lets entry points and generated links resolve from the deployment path. |
| 58 | + |
| 59 | +### Add Browser Entry Points |
| 60 | + |
| 61 | +Create a TypeScript entry point for component registration. Import each `define.js` module that the site uses: |
| 62 | + |
| 63 | +```typescript |
| 64 | +// src/_layouts/elements.ts |
| 65 | +import './elements.css'; |
| 66 | +import '@nvidia-elements/core/alert/define.js'; |
| 67 | +import '@nvidia-elements/core/button/define.js'; |
| 68 | +``` |
| 69 | + |
| 70 | +Create a CSS entry point for the global theme, font, and utility styles: |
| 71 | + |
| 72 | +```css |
| 73 | +/* src/_layouts/elements.css */ |
| 74 | +@import '@nvidia-elements/themes/fonts/inter.css'; |
| 75 | +@import '@nvidia-elements/themes/index.css'; |
| 76 | +@import '@nvidia-elements/themes/dark.css'; |
| 77 | +@import '@nvidia-elements/styles/layout.css'; |
| 78 | +@import '@nvidia-elements/styles/typography.css'; |
| 79 | +@import '@nvidia-elements/styles/view-transitions.css'; |
| 80 | +``` |
| 81 | + |
| 82 | +Load the entry points from the shared Eleventy layout: |
| 83 | + |
| 84 | +{% raw %} |
| 85 | + |
| 86 | +```html |
| 87 | +<!doctype html> |
| 88 | +<html lang="en" nve-theme="dark" nve-transition="auto"> |
| 89 | + <head> |
| 90 | + <meta charset="UTF-8" /> |
| 91 | + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| 92 | + <link rel="stylesheet" href="/_layouts/elements.css" /> |
| 93 | + <script type="module" src="/_layouts/elements.ts"></script> |
| 94 | + </head> |
| 95 | + <body nve-text="body"> |
| 96 | + {{ content | safe }} |
| 97 | + </body> |
| 98 | +</html> |
| 99 | +``` |
| 100 | + |
| 101 | +{% endraw %} |
| 102 | + |
| 103 | +Keep `define.js` imports in the browser entry point. The Eleventy configuration runs in Node.js and should not register browser components unless you configure SSR. |
| 104 | + |
| 105 | +### Use Elements in Templates |
| 106 | + |
| 107 | +Write Elements markup in HTML, JavaScript, or Markdown templates: |
| 108 | + |
| 109 | +```html |
| 110 | +<div nve-layout="column gap:md"> |
| 111 | + <nve-alert status="success" closable>Site generated successfully.</nve-alert> |
| 112 | + <nve-button interaction="emphasis"> |
| 113 | + <a href="/docs/">View documentation</a> |
| 114 | + </nve-button> |
| 115 | +</div> |
| 116 | +``` |
| 117 | + |
| 118 | +When configuring a custom Markdown library, enable inline HTML so Markdown pages can emit `nve-*` tags. The starter also extends the Markdown renderer to add `nve-text` and `nve-layout` attributes to generated headings, paragraphs, links, and lists. |
| 119 | + |
| 120 | +## Server-Side Rendering |
| 121 | + |
| 122 | +The [`@lit-labs/eleventy-plugin-lit`](https://github.com/lit/lit/tree/main/packages/labs/eleventy-plugin-lit) plugin can render Lit components into declarative shadow DOM during the Eleventy build. Lit SSR and the Eleventy plugin are experimental, so verify component compatibility before using this path in production. The [Eleventy SSR starter]({{ELEMENTS_REPO_BASE_URL}}/tree/main/projects/starters/eleventy-ssr) provides a working testbed. |
| 123 | + |
| 124 | +Install the SSR plugin and client hydration support: |
| 125 | + |
| 126 | +```shell |
| 127 | +npm install @lit-labs/eleventy-plugin-lit @lit-labs/ssr-client |
| 128 | +``` |
| 129 | + |
| 130 | +Register every component that Eleventy must render. Load the server-compatible icon module before components that can render icons: |
| 131 | + |
| 132 | +```javascript |
| 133 | +// eleventy.config.js |
| 134 | +import litPlugin from '@lit-labs/eleventy-plugin-lit'; |
| 135 | + |
| 136 | +export default function (eleventyConfig) { |
| 137 | + eleventyConfig.addPlugin(litPlugin, { |
| 138 | + mode: 'worker', |
| 139 | + componentModules: [ |
| 140 | + 'node_modules/@nvidia-elements/core/dist/icon/server.js', |
| 141 | + 'node_modules/@nvidia-elements/core/dist/alert/define.js' |
| 142 | + ] |
| 143 | + }); |
| 144 | +} |
| 145 | +``` |
| 146 | + |
| 147 | +For interactive components, load Lit hydration support before the client-side component definitions: |
| 148 | + |
| 149 | +```typescript |
| 150 | +// src/_layouts/elements.ts |
| 151 | +import '@lit-labs/ssr-client/lit-element-hydrate-support.js'; |
| 152 | +import '@nvidia-elements/core/alert/define.js'; |
| 153 | +``` |
| 154 | + |
| 155 | +The server `componentModules` list and the browser `define.js` imports must include the same interactive components. Components that do not load in the browser remain static after Eleventy renders them. |
0 commit comments