### 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(` ${greeting.getHTML({ serializableShadowRoots: true })}
              ${JSON.stringify(context.geo)}
            
`); 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 Greenwood logo ``` -------------------------------- ### 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 (
Count: {count}
); } } customElements.define('wcc-counter', Counter); ``` ```javascript // server.js — NODE_OPTIONS="--import wc-compiler/register" node server.js import { renderToString } from 'wc-compiler'; const { html } = await renderToString( new URL('./src/components/counter.jsx', import.meta.url) ); console.log(html); // // // ``` -------------------------------- ### 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}

${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 = ` `; } } } // 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) ); // // // ``` -------------------------------- ### 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

My Image

My Image ```