### Start Website Development Server
Source: https://github.com/projectevergreen/wcc/blob/master/CONTRIBUTING.md
Start the local development server for the project website.
```sh
npm run docs:dev
```
--------------------------------
### Install WCC using npm
Source: https://github.com/projectevergreen/wcc/blob/master/README.md
Install the Web Components Compiler as a development dependency in your project using npm.
```shell
$ npm install wc-compiler --save-dev
```
--------------------------------
### Use Recommended Node Version with NVM
Source: https://github.com/projectevergreen/wcc/blob/master/CONTRIBUTING.md
Use this command to switch to the recommended Node.js version if you have NVM installed.
```sh
$ nvm use
```
--------------------------------
### Setup Signal Polyfill and Effect Import Maps
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Configure import maps in your HTML's head to include the signal-polyfill and wc-compiler's effect function. Then, import Signal and assign it to the globalThis object in a module script.
```html
```
--------------------------------
### Signal Polyfill Import Map Configuration
Source: https://context7.com/projectevergreen/wcc/llms.txt
Configure the HTML import map to load the Signal polyfill and WCC effect script. This setup is required for components using inferred observability.
```html
```
--------------------------------
### Render sb-header-jsx component
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/sandbox.html
Example of rendering a custom 'sb-header-jsx' web component, likely built using JSX syntax.
```html
```
--------------------------------
### Serverless/Edge Function with Custom Elements
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/examples.md
This example demonstrates using WCC in constrained runtime environments like AWS Lambda or Netlify Edge Functions. It includes DOM shims for compatibility.
```javascript
import '../../node_modules/wc-compiler/src/dom-shim.js';
import Greeting from './components/greeting.js';
export default async function (request, context) {
const countryCode = context.geo.country.code || 'UNKNOWN';
const countryName = context.geo.country.name || 'UNKNOWN';
const greeting = new Greeting(countryCode, countryName);
greeting.connectedCallback();
const response = new Response(`
`);
response.headers.set('content-type', 'text/html');
return response;
}
```
--------------------------------
### Render sb-signal-counter-jsx component with JSX and Light DOM
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/sandbox.html
Example of rendering a 'sb-signal-counter-jsx' web component using JSX and Light DOM. It can be rendered with a specified 'count' attribute.
```html
```
--------------------------------
### Create a Custom Element with Shadow DOM
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/index.md
Define a custom element using standard JavaScript and attach a Shadow DOM for encapsulated styles and structure. This example creates a 'wcc-footer' element.
```js
const template = document.createElement('template');
template.innerHTML = `
`;
export default class Footer extends HTMLElement {
connectedCallback() {
if (!this.shadowRoot) {
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}
}
customElements.define('wcc-footer', Footer);
```
--------------------------------
### Render Component to String
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Use `renderToString` with a URL to a JavaScript entry point to get the static HTML of a custom element. The entry point can define its own tag name or be rendered without a wrapper.
```javascript
const { html } = await renderToString(new URL('./src/index.js', import.meta.url));
```
```javascript
import './components/footer.js';
import './components/header.js';
const template = document.createElement('template');
template.innerHTML = `
My Blog Post
`;
export default class Home extends HTMLElement {
connectedCallback() {
if (!this.shadowRoot) {
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}
}
```
```javascript
import './components/footer.js';
import './components/header.js';
export default class Home extends HTMLElement {
connectedCallback() {
if (!this.shadowRoot) {
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
My Website
`;
}
}
}
```
--------------------------------
### Render sb-signal-counter-tsx component
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/sandbox.html
Example of rendering a custom 'sb-signal-counter-tsx' web component. It can be rendered with default properties or with a specified 'count' attribute.
```html
```
```html
```
--------------------------------
### Render a Custom Element File to HTML with WCC
Source: https://context7.com/projectevergreen/wcc/llms.txt
Use `renderToString` to execute a custom element's `connectedCallback` server-side and get its serialized HTML. The `wrappingEntryTag` option controls whether the output includes the custom element's tag. Props can be passed to the element's constructor for SSR data injection.
```javascript
import { renderToString } from 'wc-compiler';
// src/components/footer.js
// export default class Footer extends HTMLElement {
// connectedCallback() {
// if (!this.shadowRoot) {
// this.attachShadow({ mode: 'open' });
// this.shadowRoot.innerHTML = `
//
//
// `;
// }
// }
// }
// customElements.define('wcc-footer', Footer);
const { html, metadata } = await renderToString(
new URL('./src/components/footer.js', import.meta.url)
);
console.log(html);
//
//
//
//
//
//
console.log(metadata);
// {
// 'wcc-footer': {
// instanceName: 'Footer',
// moduleURL: URL { href: 'file:///path/to/src/components/footer.js' },
// isEntry: true,
// source: '...'
// }
// }
// Disable the wrapping custom element tag
const { html: innerHtml } = await renderToString(
new URL('./src/components/footer.js', import.meta.url),
false
);
// ...
// Pass props to the element constructor (useful for SSR with file-based routing)
const { html: ssrHtml } = await renderToString(
new URL('./src/pages/post.js', import.meta.url),
false,
new Request('https://example.com/post?id=42')
);
```
--------------------------------
### Counter Component with JSX
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Example of a native HTMLElement that compiles to a zero-runtime custom element using JSX. It handles event binding and basic re-rendering. Ensure 'this' references are correctly bound for event handlers and state updates.
```tsx
export default class Counter extends HTMLElement {
count: number;
constructor() {
super();
this.count = 0;
}
connectedCallback() {
this.render(); // this is required
}
increment() {
this.count += 1;
this.render();
}
decrement() {
this.count -= 1;
this.render();
}
render() {
const { count } = this;
return (
You have clicked {count} times
);
}
}
customElements.define('wcc-counter', Counter);
```
--------------------------------
### Build Production Website
Source: https://github.com/projectevergreen/wcc/blob/master/CONTRIBUTING.md
Generate a production-ready build of the project website.
```sh
npm run docs:build
```
--------------------------------
### Serve Production Website
Source: https://github.com/projectevergreen/wcc/blob/master/CONTRIBUTING.md
Serve a production build of the project website.
```sh
npm run docs:serve
```
--------------------------------
### Auto-format Project Files
Source: https://github.com/projectevergreen/wcc/blob/master/CONTRIBUTING.md
Automatically format all project files.
```sh
npm run format
```
--------------------------------
### Run Website Tests
Source: https://github.com/projectevergreen/wcc/blob/master/CONTRIBUTING.md
Execute a single suite of tests for the website using Vitest. Ensure a production build has been generated first.
```sh
npm run test:docs
```
--------------------------------
### Run Project Tests
Source: https://github.com/projectevergreen/wcc/blob/master/CONTRIBUTING.md
Execute all project tests using npm.
```sh
npm test
```
--------------------------------
### Run Project Linters
Source: https://github.com/projectevergreen/wcc/blob/master/CONTRIBUTING.md
Execute all linters for the project.
```sh
npm run lint
```
--------------------------------
### Initialize Signal Polyfill and Event Listeners
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/sandbox.html
Sets up the Signal polyfill globally and attaches event listeners for various component interactions, including input updates and reset button clicks.
```javascript
import { Signal } from 'signal-polyfill';
globalThis.Signal = Signal;
function randomReset() {
return Math.floor(Math.random() * 100);
}
globalThis.document.addEventListener('DOMContentLoaded', () => {
const signalGreetingInput = document.getElementById('signal-greeting-input');
const signalCounterJsxResetButton = document.getElementById('signal-counter-reset');
const signalCounterJsxLightDomResetButton = document.getElementById(
'signal-counter-jsx-reset'
);
signalGreetingInput.addEventListener('keyup', (e) => {
console.log('update greeting value => ', e.target.value);
document.querySelector('sb-signal-greeting-jsx').setAttribute('name', e.target.value);
});
signalCounterJsxResetButton.addEventListener('click', () => {
document.querySelectorAll('sb-signal-counter-tsx').forEach((el) => {
el.setAttribute('count', randomReset());
});
});
signalCounterJsxLightDomResetButton.addEventListener('click', () => {
document.querySelector('sb-signal-counter-jsx').setAttribute('count', randomReset());
});
});
```
--------------------------------
### Define a Web Component
Source: https://github.com/projectevergreen/wcc/blob/master/README.md
This snippet shows how to define a basic Web Component with a template and shadow DOM. Ensure the component is exported and defined using customElements.define.
```javascript
const template = document.createElement('template');
template.innerHTML = `
`;
class Footer extends HTMLElement {
connectedCallback() {
if (!this.shadowRoot) {
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}
}
export default Footer;
customElements.define('wcc-footer', Footer);
```
--------------------------------
### `renderToString(elementURL, wrappingEntryTag?, props?)`
Source: https://context7.com/projectevergreen/wcc/llms.txt
Renders a custom element file to HTML. It takes a URL to a component file, executes its `connectedCallback` in a server-side DOM environment, and returns the serialized HTML and metadata. Optional parameters include a flag to control wrapping the output in the entry element's tag and an object for passing props to the element's constructor.
```APIDOC
## `renderToString(elementURL, wrappingEntryTag?, props?)` — Render a custom element file to HTML
### Description
Takes a `URL` pointing to a JavaScript/TypeScript/JSX file that defines a custom element, executes its `connectedCallback` in a server-side DOM environment, and returns the serialized HTML along with metadata about all registered custom elements. The optional `wrappingEntryTag` flag (default `true`) controls whether the output is wrapped in the entry element's custom tag. An optional `props` object is passed to the element's constructor for SSR data injection.
### Parameters
#### Path Parameters
- **elementURL** (URL) - Required - The URL of the custom element file.
- **wrappingEntryTag** (boolean) - Optional - Defaults to `true`. Controls whether the output is wrapped in the entry element's custom tag.
- **props** (object) - Optional - An object passed to the element's constructor for SSR data injection.
### Request Example
```js
import { renderToString } from 'wc-compiler';
const { html, metadata } = await renderToString(
new URL('./src/components/footer.js', import.meta.url)
);
console.log(html);
//
//
//
//
//
//
console.log(metadata);
// {
// 'wcc-footer': {
// instanceName: 'Footer',
// moduleURL: URL { href: 'file:///path/to/src/components/footer.js' },
// isEntry: true,
// source: '...'
// }
// }
// Disable the wrapping custom element tag
const { html: innerHtml } = await renderToString(
new URL('./src/components/footer.js', import.meta.url),
false
);
// ...
// Pass props to the element constructor (useful for SSR with file-based routing)
const { html: ssrHtml } = await renderToString(
new URL('./src/pages/post.js', import.meta.url),
false,
new Request('https://example.com/post?id=42')
);
```
### Response
#### Success Response (200)
- **html** (string) - The rendered HTML string.
- **metadata** (object) - Metadata about the registered custom elements.
```
--------------------------------
### `renderFromHTML(html, elementURLs)`
Source: https://context7.com/projectevergreen/wcc/llms.txt
Renders an HTML string containing custom elements. It takes a raw HTML string and an array of URLs for the top-level custom elements used in that HTML. WCC registers these elements, resolves their imports, and returns the fully rendered HTML and metadata. This is useful for serverless/edge environments or when the entry point is an HTML template.
```APIDOC
## `renderFromHTML(html, elementURLs)` — Render an HTML string containing custom elements
### Description
Takes a raw HTML string and an array of `URL`s for the top-level custom elements used in that HTML. WCC registers those elements, recursively resolves all their imports, and returns the fully rendered HTML and metadata. Useful for serverless/edge environments or when the entry point is an HTML template rather than a JS file.
### Parameters
#### Path Parameters
- **html** (string) - Required - The raw HTML string containing custom elements.
- **elementURLs** (Array) - Required - An array of URLs for the top-level custom elements used in the HTML.
### Request Example
```js
import { renderFromHTML } from 'wc-compiler';
const { html, metadata } = await renderFromHTML(
`
My Site
Home Page
`,
[
new URL('./src/components/header.js', import.meta.url),
new URL('./src/components/footer.js', import.meta.url),
]
);
console.log(html);
// ...
// ...
//
Home Page
// ...
//
// Example: serverless/edge function usage
export default async function handler(request) {
const { html } = await renderFromHTML(
``,
[new URL('./components/greeting.js', import.meta.url)]
);
return new Response(`${html}`, {
headers: { 'content-type': 'text/html' }
});
}
```
### Response
#### Success Response (200)
- **html** (string) - The fully rendered HTML string.
- **metadata** (object) - Metadata about the registered custom elements.
```
--------------------------------
### Run Website Tests in TDD Mode
Source: https://github.com/projectevergreen/wcc/blob/master/CONTRIBUTING.md
Run the website test suite with Vitest in watch mode for Test-Driven Development. Ensure a production build has been generated first.
```sh
npm run test:docs:tdd
```
--------------------------------
### Render sb-picture-frame component with Light DOM
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/sandbox.html
Shows how to render a 'sb-picture-frame' component with nested HTML content (Light DOM). It includes a title and an image element.
```html
```
--------------------------------
### Initialize and Update Counter DOM Elements
Source: https://github.com/projectevergreen/wcc/blob/master/test/cases/tsx-inferred-observability/fixtures/counter/effects.txt
Initializes DOM element references and sets up effects to update text content and attributes based on counter and parity changes. Ensure the 'effect' function and Counter.$$tmpl methods are available in the scope.
```javascript
this.$el0 = this.querySelector('div > span:nth-of-type(1)');
this.$el1 = this.querySelector('div > span:nth-of-type(4)');
this.$eff0 = effect(() => {
this.$el0.textContent = Counter.$$tmpl0(this.count.get());
});
this.$eff1 = effect(() => {
this.$el0.setAttribute('data-count', this.count.get());
});
this.$eff2 = effect(() => {
this.$el1.textContent = Counter.$$tmpl1(this.parity.get());
});
```
--------------------------------
### Render sb-header component
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/sandbox.html
Basic rendering of a custom 'sb-header' web component. This component appears to be a simple header element.
```html
```
--------------------------------
### Render sb-card component with Declarative Shadow DOM
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/sandbox.html
Demonstrates rendering a 'sb-card' component using Declarative Shadow DOM. It accepts 'title' and 'thumbnail' attributes for content customization.
```html
```
--------------------------------
### DOM Shim for Serverless Environments
Source: https://context7.com/projectevergreen/wcc/llms.txt
Import the WCC DOM shim in environments lacking a global DOM, such as edge functions or serverless lambdas. This polyfills essential DOM APIs.
```javascript
// In a Netlify/Cloudflare edge function or AWS Lambda where the DOM doesn't exist:
import 'wc-compiler/dom-shim';
import Greeting from './components/greeting.js';
export default async function handler(request) {
const greeting = new Greeting();
greeting.setAttribute('name', 'Edge');
await greeting.connectedCallback();
return new Response(
`${greeting.innerHTML}`,
{ headers: { 'content-type': 'text/html' } }
);
}
```
--------------------------------
### Component with Constructor Props for Data Loading
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
A component that accepts request data in its constructor to fetch and display a post. This pattern works well with file-based routing and SSR.
```javascript
export default class PostPage extends HTMLElement {
constructor(request) {
super();
const params = new URLSearchParams(request.url.slice(request.url.indexOf('?')));
this.postId = params.get('id');
}
async connectedCallback() {
const { postId } = this;
const post = await fetch(`https://jsonplaceholder.typicode.com/posts/${postId}`).then((resp) =>
resp.json(),
);
const { title, body } = post;
this.innerHTML = `
${title}
${body}
`;
}
}
```
--------------------------------
### JSX Support for Web Components with `wc-compiler/register`
Source: https://context7.com/projectevergreen/wcc/llms.txt
Enable JSX authoring for zero-runtime, web-native custom elements by registering the `wc-compiler/register` Node.js module loader. The JSX runtime directly maps to DOM operations without a virtual DOM.
```javascript
// Run with: NODE_OPTIONS="--import wc-compiler/register" node server.js
// src/components/counter.jsx
export default class Counter extends HTMLElement {
constructor() {
super();
this.count = 0;
}
connectedCallback() {
if (!this.shadowRoot) {
this.attachShadow({ mode: 'open' });
this.render();
}
}
increment() {
this.count += 1;
this.render();
}
render() {
const { count } = this;
return (
//
//
```
--------------------------------
### renderFromHTML
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Renders a string of HTML and an array of top-level custom elements into static HTML output. It recursively renders any imports from those top-level custom elements.
```APIDOC
## renderFromHTML
### Description
This function takes a string of HTML and an array of any top-level custom elements used in the HTML, and returns the static HTML output of the rendered content. WCC will follow and recursively render any imports from those top-level custom elements.
### Method
```javascript
const { html } = await renderFromHTML(htmlString, customElements)
```
### Parameters
#### Path Parameters
- **htmlString** (string) - Required - The string of HTML to render.
- **customElements** (Array) - Required - An array of URLs for the top-level custom elements used in the HTML.
### Request Example
```javascript
const { html } = await renderFromHTML(
`
WCC
Home Page
`,
[
new URL('./src/components/footer.js', import.meta.url),
new URL('./src/components/header.js', import.meta.url),
],
);
```
### Response
#### Success Response (200)
- **html** (string) - The static HTML output of the rendered content.
#### Response Example
```html
WCC
Home Page
```
```
--------------------------------
### Render sb-card-jsx component with JSX and Declarative Shadow DOM
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/sandbox.html
Demonstrates rendering a 'sb-card-jsx' component using JSX and Declarative Shadow DOM. It accepts 'title' and 'thumbnail' attributes.
```html
```
--------------------------------
### Server-Side Rendering with Custom Elements
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/examples.md
Use this snippet for server-side rendering of custom elements, similar to Next.js. It fetches data and dynamically renders components.
```javascript
import '../components/card/card.js';
export default class ArtistsPage extends HTMLElement {
async connectedCallback() {
if (!this.shadowRoot) {
const artists = await fetch('https://www.domain.com/api/artists').then((resp) => resp.json());
const html = artists
.map((artist) => {
return `
${artist.name}
`;
})
.join('');
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = html;
}
}
}
```
--------------------------------
### Server-side Rendering with WCC
Source: https://context7.com/projectevergreen/wcc/llms.txt
Render a WCC component to a string on the server using `wc-compiler`. This is useful for pre-rendering components in Node.js environments.
```javascript
// server.js
import { renderToString } from 'wc-compiler';
const { html } = await renderToString(
new URL('./src/components/greeting.ts', import.meta.url)
);
//
Hello World! 👋
```
--------------------------------
### Progressive Hydration with `hydrate` and `metadata`
Source: https://context7.com/projectevergreen/wcc/llms.txt
Use the `hydrate="true"` or `hydrate="lazy"` attribute for progressive hydration. The `metadata` object reflects this, allowing frameworks to defer client-side script loading for an islands architecture pattern.
```javascript
import { renderFromHTML } from 'wc-compiler';
const { html, metadata } = await renderFromHTML(
`
`,
[
new URL('./src/components/header.js', import.meta.url),
new URL('./src/components/counter.js', import.meta.url),
new URL('./src/components/footer.js', import.meta.url),
]
);
// metadata['wcc-counter'].hydrate === 'lazy'
const lazyComponents = Object.entries(metadata)
.filter(([, meta]) => meta.hydrate === 'lazy')
.map(([tagName, meta]) => ({ tagName, moduleURL: meta.moduleURL }));
// Generate lazy-loading
`).join('
');
const fullPage = `${lazyScripts}${html}`;
```
--------------------------------
### Opt-out of Wrapper Tag
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Pass `false` as the second argument to `renderToString` to prevent WCC from wrapping your entry point's HTML in a custom element tag.
```javascript
const { html } = await renderToString(new URL('...'), false);
```
--------------------------------
### Static Site Generation with Custom Elements
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/examples.md
This snippet shows how to use `innerHTML` for custom elements in static site generation, useful for layout components that should not use Shadow DOM. It includes basic styling and slots.
```javascript
import './components/footer.js';
import './components/header.js';
class Layout extends HTMLElement {
connectedCallback() {
this.innerHTML = `
`;
}
}
export default Layout;
```
--------------------------------
### renderToString
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Renders a JavaScript file defining a custom element to its static HTML output. It can optionally opt-out of wrapping the entry point's HTML in a custom element tag.
```APIDOC
## renderToString
### Description
This function takes a `URL` "entry point" to a JavaScript file that defines a custom element, and returns the static HTML output of its rendered contents.
### Method
```javascript
const { html } = await renderToString(entryPointUrl, [wrapInCustomElementTag = true])
```
### Parameters
#### Path Parameters
- **entryPointUrl** (URL) - Required - The URL to the JavaScript file that defines the custom element.
#### Query Parameters
- **wrapInCustomElementTag** (boolean) - Optional - Defaults to `true`. If `false`, WCC will not wrap the entry point's HTML in a custom element tag.
### Request Example
```javascript
const { html } = await renderToString(new URL('./src/index.js', import.meta.url));
```
### Response
#### Success Response (200)
- **html** (string) - The static HTML output of the rendered content.
#### Response Example
```html
WCC
Home Page
```
```
--------------------------------
### Retrieve Rendering Metadata
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Both `renderToString` and `renderFromHTML` return metadata about registered custom elements. This includes their instance names, module URLs, and whether they are entry points.
```javascript
const { metadata } = await renderToString(new URL('./src/index.js', import.meta.url));
console.log({ metadata });
/*
* {
* metadata: {
* 'wcc-footer': { instanceName: 'Footer', moduleURL: [URL], isEntry: true },
* 'wcc-header': { instanceName: 'Header', moduleURL: [URL], isEntry: true },
* 'wcc-navigation': { instanceName: 'Navigation', moduleURL: [URL], isEntry: false }
* }
* }
*/
```
--------------------------------
### Run Project Tests in TDD Mode
Source: https://github.com/projectevergreen/wcc/blob/master/CONTRIBUTING.md
Run all project tests in watch mode for Test-Driven Development.
```sh
npm test:tdd
```
--------------------------------
### Render Web Component to String with WCC
Source: https://github.com/projectevergreen/wcc/blob/master/README.md
Use the renderToString function from 'wc-compiler' to convert a Web Component instance into its HTML string representation. This requires importing the function and providing the URL of the component.
```javascript
import { renderToString } from 'wc-compiler';
const { html } = await renderToString(new URL('./path/to/component.js', import.meta.url));
```
--------------------------------
### Render HTML String
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Use `renderFromHTML` with an HTML string and an array of top-level custom element URLs to render static HTML. WCC recursively renders imported custom elements.
```javascript
const { html } = await renderFromHTML(
`
WCC
Home Page
`,
[
new URL('./src/components/footer.js', import.meta.url),
new URL('./src/components/header.js', import.meta.url),
],
);
```
--------------------------------
### RenderToString with Constructor Props
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Pass constructor props to `renderToString` for frameworks needing data orchestration. These props are passed to the custom element's constructor.
```javascript
const request = new Request({
/* ... */
});
const { html } = await renderToString(new URL(moduleUrl), false, request);
```
--------------------------------
### Metadata Extraction
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Both renderToString and renderFromHTML return metadata about all custom elements registered during rendering, including their instance name, module URL, and whether they are an entry point.
```APIDOC
## Metadata
### Description
`renderToString` and `renderFromHTML` return not only HTML, but also metadata about all the custom elements registered as part of rendering the entry file.
### Method
```javascript
const { metadata } = await renderToString(entryPointUrl);
```
### Response
#### Success Response (200)
- **metadata** (object) - An object containing metadata for each custom element.
- **[elementTagName]** (object)
- **instanceName** (string) - The name of the custom element's class.
- **moduleURL** (URL) - The URL of the module where the custom element is defined.
- **isEntry** (boolean) - Indicates if the custom element is an entry point.
### Response Example
```javascript
console.log({ metadata });
/*
* {
* metadata: {
* 'wcc-footer': { instanceName: 'Footer', moduleURL: [URL], isEntry: true },
* 'wcc-header': { instanceName: 'Header', moduleURL: [URL], isEntry: true },
* 'wcc-navigation': { instanceName: 'Navigation', moduleURL: [URL], isEntry: false }
* }
* }
*/
```
```
--------------------------------
### Enable Progressive Hydration for Custom Element
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Add `hydration="true"` to a custom element to enable progressive hydration. This hint can be used to defer script loading.
```html
```
--------------------------------
### Component-Level Server-Side Data Loading with `getData`
Source: https://context7.com/projectevergreen/wcc/llms.txt
Export an async `getData` function from your custom element module to fetch data before rendering. WCC calls this function and passes the result as props to the element's constructor.
```javascript
// src/components/artist-list.js
const template = document.createElement('template');
export default class ArtistList extends HTMLElement {
constructor(props = {}) {
super();
this.artists = props.artists ?? [];
}
connectedCallback() {
if (!this.shadowRoot) {
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
${this.artists.map(a => `
${a.name}
`).join('')}
`;
}
}
}
// getData is called automatically by WCC before instantiating the element
export async function getData() {
const artists = await fetch('https://api.example.com/artists').then(r => r.json());
return { artists };
}
customElements.define('wcc-artist-list', ArtistList);
// Render it — WCC fetches data and injects it into the constructor automatically
import { renderToString } from 'wc-compiler';
const { html } = await renderToString(
new URL('./src/components/artist-list.js', import.meta.url)
);
//
//
//
Artist One
Artist Two
//
//
```
--------------------------------
### Component with getData for Data Loading
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
A component that exports a `getData` function to inject initial state into the custom element's constructor. The data is serialized into the Shadow DOM.
```javascript
class Counter extends HTMLElement {
constructor(props = {}) {
super();
this.count = props.count;
this.render();
}
// setup your shadow root ...
render() {
this.shadowRoot.innerHTML = `
Current Count: ${this.count}
`;
}
}
export async function getData() {
return {
count: Math.floor(Math.random() * (100 - 0 + 1) + 0),
};
}
```
--------------------------------
### Generated Static HTML of a Custom Element
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/index.md
The output of WCC rendering a custom element, including its Shadow DOM content. This static HTML can be served directly.
```html
```
--------------------------------
### TypeScript Configuration for WCC
Source: https://context7.com/projectevergreen/wcc/llms.txt
Configure your tsconfig.json to enable TypeScript features compatible with WCC, including `erasableSyntaxOnly` for type stripping.
```json
// tsconfig.json
{
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "wc-compiler",
"lib": ["DOM"],
"allowImportingTsExtensions": true,
"erasableSyntaxOnly": true
}
}
```
--------------------------------
### Render Custom Element to Static HTML with WCC
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/index.md
Use the 'renderToString' function from 'wc-compiler' to process a custom element and generate its static HTML representation. This is useful for server-side rendering.
```js
import { renderToString } from 'wc-compiler';
const { html } = await renderToString(
new URL('./path/to/footer.js', import.meta.url)
);
```
--------------------------------
### Render Parity Information
Source: https://github.com/projectevergreen/wcc/blob/master/test/cases/jsx-inferred-observability/fixtures/counter/static-templates.txt
This template is used to display the parity of a value. It accepts a 'parity' argument.
```javascript
static $$tmpl2 = parity => `Parity is: ${parity}`
```
--------------------------------
### Render Top Level Count
Source: https://github.com/projectevergreen/wcc/blob/master/test/cases/jsx-inferred-observability/fixtures/counter/static-templates.txt
Use this template to display the current count in a top-level context. It takes a single 'count' argument.
```javascript
static $$tmpl1 = count => `Top level count is ${count}`
```
--------------------------------
### Render HTML String with Custom Elements using WCC
Source: https://context7.com/projectevergreen/wcc/llms.txt
Use `renderFromHTML` to render an HTML string containing custom elements. Provide an array of URLs for the top-level custom elements to be registered and resolved. This is useful for serverless or edge environments.
```javascript
import { renderFromHTML } from 'wc-compiler';
const { html, metadata } = await renderFromHTML(
`
My Site
Home Page
`,
[
new URL('./src/components/header.js', import.meta.url),
new URL('./src/components/footer.js', import.meta.url),
]
);
console.log(html);
// ...
// ...
//
Home Page
// ...
//
// Example: serverless/edge function usage
export default async function handler(request) {
const { html } = await renderFromHTML(
``,
[new URL('./components/greeting.js', import.meta.url)]
);
return new Response(`${html}`, {
headers: { 'content-type': 'text/html' }
});
}
```
--------------------------------
### HTML Rendering and Lazy Hydration Handler
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/examples.md
Renders HTML from a string, extracts metadata for lazy-loaded JavaScript modules, and constructs an HTML response. It uses IntersectionObserver to trigger the import of lazy modules based on element visibility.
```js
import { renderFromHTML } from 'wc-compiler';
export async function handler() {
const { html, metadata } = await renderFromHTML(`
`);
const lazyJs = [];
for (const asset in metadata) {
const a = metadata[asset];
a.tagName = asset;
if (a.moduleURL.href.endsWith('.js')) {
if (a.hydrate === 'lazy') {
lazyJs.push(a);
}
}
}
return {
status: 200,
headers: {
'cache-control': 'no-cache, no-store, must-revalidate, max-age=0, s-maxage=0',
'content-type': 'text/html; charset=utf8',
},
body: `
${lazyJs
.map((script) => {
returnsubsetneq
`;
})
.join('
')}
${html}
`,
};
}
```
--------------------------------
### NodeJS JSX Execution Command
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Command to execute a JavaScript file with JSX support using the wc-compiler register flag. This is required for running WCC with JSX.
```shell
$ NODE_OPTIONS="--import wc-compiler/register" node your-script.js
```
--------------------------------
### Enable Inferred Observability (Signals) in WCC Component
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Enable inferred observability by exporting `inferredObservability = true;`. This maps Signal reads to observed attributes and automatically handles attributeChangedCallback updates and effect management.
```jsx
export const inferredObservability = true;
export default class Counter extends HTMLElement {
constructor() {
super();
// using TC39 signals
this.count = new Signal.State(0);
this.parity = new Signal.Computed(() => (this.count.get() % 2 === 0 ? 'even' : 'odd'));
}
connectedCallback() {
if (!this.shadowRoot) {
this.attachShadow({
mode: 'open',
});
// this call is still needed
this.render();
}
}
increment() {
this.count.set(this.count.get() + 1);
}
decrement() {
this.count.set(this.count.get() - 1);
}
render() {
const { count, parity } = this;
return (
The count is {count.get()} ({parity.get()})
);
}
}
customElements.define('wcc-counter', Counter);
```
--------------------------------
### Parity Display Template
Source: https://github.com/projectevergreen/wcc/blob/master/test/cases/tsx-inferred-observability/fixtures/counter/static-templates.txt
Renders the parity (even/odd) of the counter. Use for indicating the parity status.
```javascript
static $$tmpl1 = parity => `Parity is: ${parity}`
```
--------------------------------
### Update Greeting Text with Effect
Source: https://github.com/projectevergreen/wcc/blob/master/test/cases/tsx-inferred-observability/fixtures/greeting/effects.txt
Use an effect to update the text content of an element based on a reactive property. This is useful for displaying dynamic data like user greetings.
```javascript
this.$el0 = this.querySelector('h3:nth-of-type(1)');
this.$eff0 = effect(() => {
this.$el0.textContent = Greeting.$$tmpl0(this.name.get());
});
```
--------------------------------
### Enable Declarative Shadow DOM in WCC Component
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
To enable Declarative Shadow DOM, call attachShadow({ mode: 'open' }) in your component's connectedCallback before rendering. This ensures the shadowRoot is available for client-side mounting.
```js
export default class Counter extends HTMLElement {
constructor() {
super();
this.count = 0;
}
connectedCallback() {
if (!this.shadowRoot) {
this.attachShadow({ mode: 'open' }); // this is required for DSD support
this.render();
}
}
// ...
}
customElements.define('wcc-counter', Counter);
```
--------------------------------
### tsconfig.json for WCC JSX
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/docs.md
Required tsconfig.json settings for WCC to process JSX. Ensure 'jsx' is set to 'preserve' and 'jsxImportSource' is 'wc-compiler'. Additional recommended options include 'allowImportingTsExtensions' and 'erasableSyntaxOnly'.
```json5
{
"compilerOptions": {
// required options
"jsx": "preserve",
"jsxImportSource": "wc-compiler",
"lib": ["DOM"],
// additional recommended options
"allowImportingTsExtensions": true,
"erasableSyntaxOnly": true
}
}
```
--------------------------------
### HTML Structure for Picture Frame Component
Source: https://github.com/projectevergreen/wcc/blob/master/docs/pages/examples.md
This HTML defines the content passed as children to the custom element. It includes a heading and an image.
```html