{"id":13515185,"url":"https://github.com/11ty/webc","last_synced_at":"2025-05-16T04:03:55.558Z","repository":{"id":58949142,"uuid":"534705484","full_name":"11ty/webc","owner":"11ty","description":"Single File Web Components","archived":false,"fork":false,"pushed_at":"2023-07-02T10:20:06.000Z","size":542,"stargazers_count":1368,"open_issues_count":80,"forks_count":41,"subscribers_count":17,"default_branch":"main","last_synced_at":"2025-05-16T01:28:52.538Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/11ty.png","metadata":{"funding":{"open_collective":"11ty"},"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-09-09T15:45:23.000Z","updated_at":"2025-05-13T18:14:00.000Z","dependencies_parsed_at":"2023-02-01T01:45:33.439Z","dependency_job_id":"ba5e21d4-1f74-4645-85fe-6bb4e8d2a59d","html_url":"https://github.com/11ty/webc","commit_stats":{"total_commits":358,"total_committers":12,"mean_commits":"29.833333333333332","dds":0.06145251396648044,"last_synced_commit":"a2f548c23490929aa8c9cd25159549eba3e869c7"},"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/11ty%2Fwebc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/11ty%2Fwebc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/11ty%2Fwebc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/11ty%2Fwebc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/11ty","download_url":"https://codeload.github.com/11ty/webc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254464891,"owners_count":22075570,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T05:01:07.274Z","updated_at":"2025-05-16T04:03:55.534Z","avatar_url":"https://github.com/11ty.png","language":"JavaScript","funding_links":["https://opencollective.com/11ty"],"categories":["JavaScript","Meta Frameworks","others"],"sub_categories":["Svelte"],"readme":"# WebC is for Single File Web Components\n\n## Features\n\n* Framework-independent standalone HTML serializer for generating markup for Web Components.\n\t* Expand any HTML element (including custom elements and web components) to HTML with defined conventions from web standards.\n\t* This means that Web Components created with WebC are compatible with server-side rendering (without duplicating author-written markup).\n* Compilation tools to aggregate component-level assets (CSS or JS) for critical CSS or client JavaScript.\n* Opt-in to scope your component CSS using WebC’s built-in CSS prefixer.\n\t* Or, use browser-native Shadow DOM style scoping (for future-compatibility when Declarative Shadow DOM browser support is ubiquitous)\n* Progressive-enhancement friendly. \n* Streaming friendly.\n* Shadow DOM friendly.\n* Async friendly.\n\n### Integrations/Plugins\n\n* [`@11ty/eleventy-plugin-webc`](https://www.11ty.dev/docs/languages/webc/) adds WebC to [Eleventy](https://www.11ty.dev/)\n* [`express-webc`](https://github.com/NickColley/express-webc) by [@NickColley](https://github.com/NickColley/) adds WebC to [Express](https://expressjs.com/)\n* [`koa-webc`](https://github.com/sombriks/koa-webc) by [@sombriks](https://github.com/sombriks) adds WebC to [Koa](https://koajs.com/)\n\n### Testimonials\n\n\u003e “javascript frameworks are dead to me”—[Andy Bell](https://twitter.com/hankchizljaw/status/1568301299623411715)\n\n\u003e “The DX and authoring model you landed on here looks fantastic”—[Addy Osmani](https://twitter.com/addyosmani/status/1568741911690899457)\n\n\u003e “Really like the programmatic API approach over using a bundler to pre-compile and then serve.”—[Harminder Virk](https://twitter.com/AmanVirk1/status/1568312188292546566)\n\n### Similar Works\n\nFolks doing similar things with Web Components: check them out!\n\n* [Enhance](https://enhance.dev/docs/)\n* [wcc](https://github.com/ProjectEvergreen/wcc)\n* [Lit SSR](https://lit.dev/docs/ssr/overview/) with plugins for [Eleventy](https://github.com/lit/lit/tree/main/packages/labs/eleventy-plugin-lit#lit-labseleventy-plugin-lit), [Astro](https://docs.astro.build/en/guides/integrations-guide/lit/), and [Rocket](https://rocket.modern-web.dev/docs/basics/components/)\n\n## Installation\n\nNote: if you’re **not** building a plugin or integration for WebC, you can probably skip this section!\n\nIt’s available on [npm as `@11ty/webc`](https://www.npmjs.com/package/@11ty/webc):\n\n```\nnpm install @11ty/webc\n```\n\nThis is an ESM project and as such requires a `\"type\": \"module\"` in your `package.json` (or use the `.mjs` file extension).\n\n```js\nimport { WebC } from \"@11ty/webc\";\n```\n\nYou _can_ use this in a CommonJS file via dynamic import:\n\n```js\n(async function() {\n\tconst { WebC } = await import(\"@11ty/webc\");\n})();\n```\n\n## Examples\n\n### JavaScript API\n\n```js\nimport { WebC } from \"@11ty/webc\";\n\nlet page = new WebC();\n\n// This enables aggregation of CSS and JS\n// As of 0.4.0+ this is disabled by default\npage.setBundlerMode(true);\n\n// File\npage.setInputPath(\"page.webc\");\n\n// Or, a String\n// page.setContent(`\u003cp\u003eHello!\u003c/p\u003e`);\n\nlet { html, css, js, components } = await page.compile();\n\n// Or, Readable Streams for each\nlet { html, css, js } = await page.stream();\n```\n\n### It’s HTML\n\nIf 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 `\u003ctemplate\u003e` for markup). Using `\u003ctemplate\u003e` in a WebC file will output 👀 a `\u003ctemplate\u003e` element.\n\n```html\n\u003c!doctype html\u003e\n\u003chtml lang=\"en\"\u003e\n\t\u003chead\u003e\n\t\t\u003cmeta charset=\"utf-8\"\u003e\n\t\t\u003ctitle\u003eWebC Example\u003c/title\u003e\n\t\u003c/head\u003e\n\t\u003cbody\u003e\n\t\tWebC *is* HTML.\n\t\u003c/body\u003e\n\u003c/html\u003e\n```\n\n* Uses [`parse5`](https://github.com/inikulin/parse5) to parse WebC HTML as modern browsers do (credit to [@DasSurma’s](https://twitter.com/DasSurma/status/1559159122964127744) work with [Vite](https://twitter.com/patak_dev/status/1564265006627176449) here)\n* `\u003c!doctype html\u003e` is optional (will be added automatically if the content starts with `\u003chtml`).\n* Throws a helpful error if it encounters quirks mode markup.\n\n### HTML Imports (kidding… kinda)\n\nTo use components, we provide a few options: registering them globally via JavaScript or dynamically declaratively importing directly in your WebC file via `webc:import`.\n\n#### Register global components\n\n```js\nimport { WebC } from \"@11ty/webc\";\n\nlet page = new WebC();\n\n// Pass in a glob, using the file name as component name\npage.defineComponents(\"components/**.webc\");\n\n// Array of file names, using file name as component name\npage.defineComponents([\"components/my-component.webc\"]);\n\n// Object maps component name to file name\npage.defineComponents({\n\t\"my-component\": \"components/my-component.webc\"\n});\n```\n\nAnd now you can use them in your WebC files without importing!\n\nConsider this `page.webc` file:\n\n```html\n\u003c!doctype html\u003e\n\u003ctitle\u003eWebC Example\u003c/title\u003e\n\u003cmy-component\u003e\u003c/my-component\u003e\n```\n\nWhen compiled, this will expand `\u003cmy-component\u003e` to include the contents inside of `components/my-component.webc`.\n\nIf the `components/my-component.webc` file contains:\n\n```html\nComponents don’t need a root element, y’all.\n```\n\nCompiling `page.webc` will return the following HTML:\n\n```html\n\u003c!doctype html\u003e\n\u003chtml\u003e\n\t\u003chead\u003e\n\t\t\u003ctitle\u003eWebC Example\u003c/title\u003e\n\t\u003c/head\u003e\n\u003cbody\u003e\n\tComponents don’t need a root element, y’all.\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nTricky 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](https://www.11ty.dev/docs/plugins/image/) to optimize all images in your project.\n\n#### Dynamic import\n\nSee [_`webc:import` on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#webcimport)\n\n### Remapping components\n\nSee [_`webc:is` on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#webcis)\n\n### Component Markup\n\n#### Keep that host component HTML\n\nSee [_`webc:keep` on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#webckeep)\n\n#### Slots\n\nSee [_Slots on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#slots)\n\n### Aggregating CSS and JS\n\nEnabling 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).\n\nAs noted in the JavaScript API section above, the `compile` method returns four different properties:\n\n```js\npage.setBundlerMode(true);\n\nlet { html, css, js, components } = await page.compile();\n```\n\nBy default, `\u003cstyle\u003e` and `\u003cscript\u003e` 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 `\u003clink rel=\"stylesheet\"\u003e` and `\u003cscript src\u003e` when the URLs point to files on the file system ([remote URL sources are not yet supported](https://github.com/11ty/webc/issues/15))_.\n\nNote that if a `\u003cstyle\u003e` is nested inside of [declarative shadow root](https://web.dev/declarative-shadow-dom/) template (e.g. `\u003ctemplate shadowrootmode\u003e` or the deprecated `\u003ctemplate shadowroot\u003e`), it is also left as is and not aggregated.\n\nYou can also opt out of aggregation on a per-element basis using `\u003cstyle webc:keep\u003e` or `\u003cscript webc:keep\u003e`. \n\n`page.webc`:\n\n```html\n\u003cmy-component\u003eDefault slot\u003c/my-component\u003e\n```\n\n`components/my-component.webc`:\n\n```html\n\u003cstyle\u003e\nmy-component {\n\tcolor: rebeccapurple;\n}\n\u003c/style\u003e\n```\n\nCompilation results:\n\n```js\npage.setBundlerMode(true);\n\nlet results = await page.compile();\n\n// `results`:\n{\n\thtml: \"\u003cmy-component\u003eDefault slot\u003c/my-component\u003e\",\n\tcss: [\"my-component { color: rebeccapurple; }\"],\n\tjs: [],\n\tcomponents: [\"page.webc\", \"components/my-component.webc\"]\n}\n```\n\nThe 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).\n\n#### Scoped CSS\n\nSee [_`webc:scoped` on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#webcscoped)\n\n### Custom Transforms\n\nYou can also transform individual element content using the `setTransform` method.\n\n```js\nlet component = new WebC();\nlet md = new MarkdownIt({ html: true });\n\ncomponent.setTransform(\"md\", async (content) =\u003e {\n\t// async-friendly\n\treturn md.render(content);\n});\n```\n\nNow you can automatically transform markdown in your WebC templates via the `webc:type` attribute.\n\n```html\n\u003ctemplate webc:type=\"md\"\u003e\n# Header\n\u003c/template\u003e\n```\n\nCompiles to:\n\n```html\n\u003ch1\u003eHeader\u003c/h1\u003e\n```\n\n* Bonus feature: `webc:type` supports a comma separated list of transforms.\n\nNote that the `\u003ctemplate webc:type\u003e` node is compiled away. If you’d like to keep it around, use `webc:keep` (e.g. `\u003ctemplate webc:type webc:keep\u003e`).\n\nWe 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!\n\n### Conditionals\n\nSee [_`webc:if` on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#webcif)\n\n### Loops\n\nSee [_`webc:for` on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#webcfor-loops)\n\n### Attributes\n\nSee [_Attributes and `webc:root` on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#attributes-and-webcroot)\n\n#### Properties (or Props)\n\nSee [_Props (properties) on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#props-(properties))\n\n#### Dynamic attributes and properties\n\nSee [_Dynamic Attributes and Properties on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#dynamic-attributes-and-properties)\n\n#### Setting multiple attributes\n\nSee [_`@attributes` on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#@attributes)\n\n### JavaScript Render Functions\n\nSee [_`webc:type` (JavaScript Render Functions) on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#webctype-(javascript-render-functions))\n\n### Setting HTML\n\nSee [_`@html` on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#@html)\n\n### Setting Text\n\nSee [_`@text` on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#@text)\n\n### Helper Functions\n\nIf you want to add custom JavaScript functions for use in render functions, `@html`, or dynamic attributes you can use the `setHelper` method.\n\n```js\nimport { WebC } from \"@11ty/webc\";\n\nlet page = new WebC();\n\npage.setHelper(\"alwaysBlue\", () =\u003e {\n\treturn \"Blue\"\n});\n```\n\nAnd `alwaysBlue()` is now available:\n\n```html\n\u003cscript webc:type=\"js\"\u003e\nalwaysBlue()\n\u003c/script\u003e\n```\n\n### Raw Content (no WebC processing)\n\nSee [_`webc:raw` on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#webcraw)\n\n## Subtleties and Limitations\n\nSee [_Subtleties and Limitations on the WebC Reference_](https://www.11ty.dev/docs/languages/webc/#subtleties-and-limitations)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F11ty%2Fwebc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F11ty%2Fwebc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F11ty%2Fwebc/lists"}