Renderer plugins allow users to customize how Greenwood server renders (and prerenders) your project. By default, Greenwood just supports using (template) strings to return static HTML for the content and template of your server side routes. For example, using Lit SSR to render Lit Web Components server side.


Given that rendering Web Components on the server side often involves implementations needing to patch the NodeJS globals space or more complex needs like running an entire headless browser, Greenwood provides a couple ways to manage the rendering lifecycle.

const greenwoodPluginMyCustomRenderer = (options = {}) => {
  return {
    type: 'renderer',
    name: 'plugin-renderer-custom',
    provider: () => {
      return {
        workerUrl: new URL('./my-ssr-route-worker.js', import.meta.url),
        prerender: options.prerender

export {


  • workerUrl (recommended) - URL to the location of a file with a worker thread implementation to use for rendering.
  • customUrl - URL to a file that has a default export of a function for handling the prerendering lifecyle of a Greenwood build, and running the provided callback function
  • prerender (optional) - Flag can be used to indicate if this custom renderer should be used to statically prerender pages too.



The recommended Greenwood API for executing server rendered code is in a Worker thread, to avoid global namespace and API collisions. Each worker is expected to implement the API of default export, getBody, getTemplate, and getFrontmatter.

You can follow the WCC default implementation for Greenwood as a reference.

Custom Implementation

This option is useful for exerting full control over the rendering lifecycle. You can follow Greenwood's implementation for Puppeteer as a reference.