Almost all modern framworks provide a way to server side render (SSR) a web site by running the framework code on a JavaScipt server side framework, such as express, to produce an intial string of HTML that can be sent to the browser. The same component code that runs in the browser is also run on the server.
With Web Components there are several limitations when it comes to SSR:
it’s not possible to run the same code on the server since Web Components rely on browser specific DOM APIs that are not available unless you fire up a headless browser or an alternative DOM implementation. Both of these solutions bring a non-trivial overhead that is hard to justify.
Shadow DOM cannot (currently) be represented declaratively so you cannot send it over in your initial string of HTML. Instead you’ll need to implement some other style encapsulation solution (much like the frameworks do.)
So Web Components are certainly at a disadvantage here compared to framework components, but they still offer two main advantages:
less code that runs faster as they use built in platform APIs
future proof as they can be used anywhere, including within current and future frameworks, without modification or risk of obsolesence.
So if these advantages are enough for you to choose Web Components over framework components, how can you SSR Web Components? Well since Web Components without the Shadow DOM are just standard HTML, it’s straightforward.
On the client
Our initial, browser based, web component may look something like this:
However, to render this on the server you can’t use HTMLElement, customElements or addEventListener for example as those APIs don’t exist on the server, so you’ll need to extract the template method into a standalone function that can be used:
and update our browser based component definition to import and use that function:
On the server
On the server, while constructing the page response you need to use the HTML tag for our component with the necessary attributes that will be parsed by the browser, and for the SSR content of the component use the same template function as above:
In summary, you can SSR web components without any server side DOM implementation, but only without the Shadow DOM.