• Stars
    star
    1,163
  • Rank 40,128 (Top 0.8 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 2 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Single File Web Components

WebC is for Single File Web Components

Features

  • Framework-independent standalone HTML serializer for generating markup for Web Components.
    • Expand any HTML element (including custom elements and web components) to HTML with defined conventions from web standards.
    • This means that Web Components created with WebC are compatible with server-side rendering (without duplicating author-written markup).
  • Compilation tools to aggregate component-level assets (CSS or JS) for critical CSS or client JavaScript.
  • Opt-in to scope your component CSS using WebC’s built-in CSS prefixer.
    • Or, use browser-native Shadow DOM style scoping (for future-compatibility when Declarative Shadow DOM browser support is ubiquitous)
  • Progressive-enhancement friendly.
  • Streaming friendly.
  • Shadow DOM friendly.
  • Async friendly.

Integrations/Plugins

Testimonials

“javascript frameworks are dead to me”—Andy Bell

“The DX and authoring model you landed on here looks fantastic”—Addy Osmani

“Really like the programmatic API approach over using a bundler to pre-compile and then serve.”—Harminder Virk

Similar Works

Folks doing similar things with Web Components: check them out!

Installation

Note: if you’re not building a plugin or integration for WebC, you can probably skip this section!

It’s available on npm as @11ty/webc:

npm install @11ty/webc

This is an ESM project and as such requires a "type": "module" in your package.json (or use the .mjs file extension).

import { WebC } from "@11ty/webc";

You can use this in a CommonJS file via dynamic import:

(async function() {
	const { WebC } = await import("@11ty/webc");
})();

Examples

JavaScript API

import { WebC } from "@11ty/webc";

let page = new WebC();

// This enables aggregation of CSS and JS
// As of 0.4.0+ this is disabled by default
page.setBundlerMode(true);

// File
page.setInputPath("page.webc");

// Or, a String
// page.setContent(`<p>Hello!</p>`);

let { html, css, js, components } = await page.compile();

// Or, Readable Streams for each
let { html, css, js } = await page.stream();

It’s HTML

If WebC looks familiar, that’s because WebC is HTML. These are single file HTML components but don’t require any special element conventions (for example Vue’s single file component uses a top-level <template> for markup). Using <template> in a WebC file will output 👀 a <template> element.

<!doctype html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>WebC Example</title>
	</head>
	<body>
		WebC *is* HTML.
	</body>
</html>
  • Uses parse5 to parse WebC HTML as modern browsers do (credit to @DasSurma’s work with Vite here)
  • <!doctype html> is optional (will be added automatically if the content starts with <html).
  • Throws a helpful error if it encounters quirks mode markup.

HTML Imports (kidding… kinda)

To use components, we provide a few options: registering them globally via JavaScript or dynamically declaratively importing directly in your WebC file via webc:import.

Register global components

import { WebC } from "@11ty/webc";

let page = new WebC();

// Pass in a glob, using the file name as component name
page.defineComponents("components/**.webc");

// Array of file names, using file name as component name
page.defineComponents(["components/my-component.webc"]);

// Object maps component name to file name
page.defineComponents({
	"my-component": "components/my-component.webc"
});

And now you can use them in your WebC files without importing!

Consider this page.webc file:

<!doctype html>
<title>WebC Example</title>
<my-component></my-component>

When compiled, this will expand <my-component> to include the contents inside of components/my-component.webc.

If the components/my-component.webc file contains:

Components don’t need a root element, y’all.

Compiling page.webc will return the following HTML:

<!doctype html>
<html>
	<head>
		<title>WebC Example</title>
	</head>
<body>
	Components don’t need a root element, y’all.
</body>
</html>

Tricky trick: you aren’t limited to custom element names (e.g. my-component) here. You can use p, blockquote, h1, or any tag name to remap any HTML element globally. A more useful example might be an img component that uses the Eleventy Image utility to optimize all images in your project.

Dynamic import

See webc:import on the WebC Reference

Remapping components

See webc:is on the WebC Reference

Component Markup

Keep that host component HTML

See webc:keep on the WebC Reference

Slots

See Slots on the WebC Reference

Aggregating CSS and JS

Enabling Bundler Mode (page.setBundlerMode(true)) aggregates CSS and JS found in WebC components. Bundler mode is disabled by default (but enabled by default in the Eleventy WebC plugin).

As noted in the JavaScript API section above, the compile method returns four different properties:

page.setBundlerMode(true);

let { html, css, js, components } = await page.compile();

By default, <style> and <script> elements in component files are removed from individual component markup and aggregated together for re-use elsewhere (you could write this to a file, or use as Critical CSS in another layout template—the Eleventy plugin will smooth this over for you). This includes <link rel="stylesheet"> and <script src> when the URLs point to files on the file system (remote URL sources are not yet supported).

Note that if a <style> is nested inside of declarative shadow root template (e.g. <template shadowrootmode> or the deprecated <template shadowroot>), it is also left as is and not aggregated.

You can also opt out of aggregation on a per-element basis using <style webc:keep> or <script webc:keep>.

page.webc:

<my-component>Default slot</my-component>

components/my-component.webc:

<style>
my-component {
	color: rebeccapurple;
}
</style>

Compilation results:

page.setBundlerMode(true);

let results = await page.compile();

// `results`:
{
	html: "<my-component>Default slot</my-component>",
	css: ["my-component { color: rebeccapurple; }"],
	js: [],
	components: ["page.webc", "components/my-component.webc"]
}

The order of aggregated styles and scripts is based on the dependency graph of the components in play (the order is noted in the components array, a list of component file names).

Scoped CSS

See webc:scoped on the WebC Reference

Custom Transforms

You can also transform individual element content using the setTransform method.

let component = new WebC();
let md = new MarkdownIt({ html: true });

component.setTransform("md", async (content) => {
	// async-friendly
	return md.render(content);
});

Now you can automatically transform markdown in your WebC templates via the webc:type attribute.

<template webc:type="md">
# Header
</template>

Compiles to:

<h1>Header</h1>
  • Bonus feature: webc:type supports a comma separated list of transforms.

Note that the <template webc:type> node is compiled away. If you’d like to keep it around, use webc:keep (e.g. <template webc:type webc:keep>).

We do provide two built-in transforms in WebC: JavaScript Render Functions (webc:type="render") and CSS scoping (webc:scoped). Those are covered in separate sections. You can override these with the setTransform API but it is generally recommended to add your own named transform!

Conditionals

See webc:if on the WebC Reference

Loops

See webc:for on the WebC Reference

Attributes

See Attributes and webc:root on the WebC Reference

Properties (or Props)

See Props (properties) on the WebC Reference

Dynamic attributes and properties

See Dynamic Attributes and Properties on the WebC Reference

Setting multiple attributes

See @attributes on the WebC Reference

JavaScript Render Functions

See webc:type (JavaScript Render Functions) on the WebC Reference

Setting HTML

See @html on the WebC Reference

Setting Text

See @text on the WebC Reference

Helper Functions

If you want to add custom JavaScript functions for use in render functions, @html, or dynamic attributes you can use the setHelper method.

import { WebC } from "@11ty/webc";

let page = new WebC();

page.setHelper("alwaysBlue", () => {
	return "Blue"
});

And alwaysBlue() is now available:

<script webc:type="js">
alwaysBlue()
</script>

Raw Content (no WebC processing)

See webc:raw on the WebC Reference

Subtleties and Limitations

See Subtleties and Limitations on the WebC Reference

More Repositories

1

eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
JavaScript
16,829
star
2

eleventy-base-blog

A starter repository for a blog web site using the Eleventy static site generator.
Nunjucks
990
star
3

11ty-website

Documentation site for the Eleventy static site generator.
JavaScript
414
star
4

eleventy-img

Utility to perform build-time image transformations.
JavaScript
385
star
5

is-land

A new performance-focused way to add interactive client-side components to your web site.
JavaScript
351
star
6

eleventy-plugin-vue

Use Vue.js templates and Vue.js single file components in Eleventy.
JavaScript
188
star
7

eleventy-fetch

Utility to cache any remote asset: Image, Video, Web Font, CSS, JSON, etc
JavaScript
122
star
8

eleventy-plugin-syntaxhighlight

A pack of Eleventy plugins for syntax highlighting in Markdown, Liquid, and Nunjucks templates.
JavaScript
115
star
9

eleventy-plugin-webc

Adds support for WebC *.webc files to Eleventy
JavaScript
104
star
10

eleventy-plugin-vite

A plugin to use Vite with Eleventy
JavaScript
104
star
11

api-screenshot

A service to add web page screenshots to your Eleventy sites.
JavaScript
97
star
12

eleventy-navigation

A plugin for creating hierarchical navigation in Eleventy projects. Supports breadcrumbs too!
JavaScript
92
star
13

eleventy-dev-server

A minimal generic web-development web server.
JavaScript
86
star
14

eleventy-activity-feed

Create one centralized RSS feed for all of the content you create across the web (aggregates from Twitter, RSS, Atom, Mastodon, YouTube)
JavaScript
81
star
15

eleventy-plugin-rss

A pack of Eleventy plugins for generating an RSS feed.
JavaScript
78
star
16

demo-eleventy-serverless

Run Eleventy in a serverless function
JavaScript
58
star
17

eleventy-upgrade-help

Helper plugin when upgrading your Eleventy project to a new major version.
JavaScript
52
star
18

api-indieweb-avatar

Return an optimized avatar image from a domain name input.
JavaScript
50
star
19

eleventy-plugin-bundle

Little bundles of code, little bundles of joy.
JavaScript
48
star
20

eleventy-plugin-inclusive-language

A linter plugin to check for inclusive language in markdown files.
JavaScript
39
star
21

demo-eleventy-serverless-oauth

A demo project using OAuth to secure some of your Eleventy Serverless routes.
JavaScript
38
star
22

eleventy-base-webc

A minimalist bare-bones starter project using Eleventy and WebC.
JavaScript
36
star
23

eleventy-assets

Code-split your CSS in Eleventy.
JavaScript
30
star
24

11ty-community

29
star
25

api-opengraph-image

A service that returns an optimized OpenGraph Image from a domain name input.
JavaScript
24
star
26

api-sparkline

Service to return sparkline SVG images.
JavaScript
19
star
27

eleventy-plugin-directory-output

Group and sort Eleventy’s verbose output by directory (and show file size with benchmarks)
JavaScript
17
star
28

tugboat

A modern starter project using Eleventy and WebC.
HTML
17
star
29

eleventy-server-browsersync

An Eleventy server plugin to use Browsersync with Eleventy 2.0+.
JavaScript
13
star
30

demo-eleventy-edge

Liquid
12
star
31

giffleball

Giffleball is a web site for Gifs
HTML
12
star
32

eleventy-community

A repository for Eleventy community discussions.
10
star
33

demo-eleventy-img-netlify-cache

A demo to show how to re-use Eleventy Image’s disk cache across Netlify builds.
JavaScript
10
star
34

eleventy-utils

Lower level internal utilities to share amongst Eleventy packages
JavaScript
9
star
35

api-img

A runtime service to optimize hosted images.
JavaScript
8
star
36

api-explorer

A simple way to browse the different runtime services provided by Eleventy
Nunjucks
8
star
37

demo-webc-counter

A progressively enhanced server-rendered form-aware web component counter using WebC
JavaScript
8
star
38

demo-eleventy-js-front-matter

Demo of free-form JavaScript in front matter to populate the Data Cascade.
Nunjucks
8
star
39

eleventy-benchmark

Eleventy Benchmark Speed Regression Test
HTML
8
star
40

11ty-logo

11ty logo built for a browser.
JavaScript
7
star
41

eleventy-dependency-tree

Returns an unordered array of local paths to dependencies of a node JavaScript file (everything it or any of its dependencies require()s)
JavaScript
7
star
42

eleventy-plugin-img

A plugin to perform runtime image transformations.
JavaScript
6
star
43

eleventy-img-cloud

Run eleventy-img in the CLOUD ⛅️
JavaScript
6
star
44

eleventy-data-transistor-fm

An Eleventy data plugin to source transistor.fm episodes.
JavaScript
5
star
45

api-generator

Find the <meta name="generator"> for a web site
JavaScript
4
star
46

demo-webc-image-compare

Server rendered image comparison web components built using WebC
JavaScript
4
star
47

lodash-custom

A custom, focused build of lodash exclusively for use internally in Eleventy.
JavaScript
4
star
48

demo-webc-shadow-dom

Demo of rendering modes of WebC components: Shadow DOM versus HTML
JavaScript
3
star
49

eleventy-base-plugin

A starter project for a Plugin for the Eleventy static site generator.
JavaScript
3
star
50

eleventy-import-disqus

A manual process to import existing exported disqus.xml content into an eleventy blog.
JavaScript
2
star
51

.github

Special README repository
Shell
1
star
52

demo-eleventy-upgrade-help

A test project to demonstrate usage of the eleventy-upgrade-help plugin
JavaScript
1
star
53

eleventy-sample-jstl

An Eleventy sample project using JSTL files.
1
star
54

demo-eleventy-from-scratch-blog

Companion code to the “6 Minutes to Build a Blog from Scratch” tutorial
HTML
1
star