@microsoft/fast-ssr
TypeScript icon, indicating that this package has built-in type declarations

1.0.0-beta.2 • Public • Published

FAST SSR

License: MIT npm version

The @microsoft/fast-ssr package contains a NodeJS solution for rendering FAST templates and components. While primarily intended for supporting server-side rendering (SSR) scenarios, it also allows FAST to be used as a general purpose HTML templating solution.

Requirements

Important Notes

@microsoft/fast-ssr is built using ES modules. This documentation assumes all JavaScript is run as ES module scripts. If that is not the case in your project, you can force ES module format by converting .js extensions to .mjs. Details on this here.

Design Philosophy

Performance is a core tenant of this package. To help achieve that, it avoids needing a comprehensive DOM implementation to render components, instead relying on a minimal set of DOM globals provided by the packaged DOM shim. Doing so comes with an important idea to understand; non-custom elements (<div>, <p>, etc) are never instantiated as JavaScript objects and you cannot gain references to these elements declared in a template. The parts of a template containing these elements are emitted as-is to the SSR string result (with any bindings evaluated). It is for this reason certain directives are no-ops. Additionally, components are rendered using only their template. Imperative code that adds elements or DOM content to a component will be invisible to the template renderer and will not be yielded in the final string result.

Community Alignment

@microsoft/fast-ssr internally implements the ElementRenderer interface proposed here and implemented in @lit-labs/ssr. The ElementRenderer interface allows Custom Elements created by different component authoring libraries to be rendered side-by-side, maximizing the portability and interoperability of Web Components. For more on how to do that, see the section on configuring the RenderInfo object.

Installation

Install @microsoft/fast-ssr and @microsoft/fast-element using your package manager of choice:

npm install --save @microsoft/fast-ssr @microsoft/fast-element

Usage

Installing the DOM Shim

@microsoft/fast-ssr requires a minimal DOM implementation to function. Install the shim by importing it. Doing so will ensure availability of certain DOM globals like HTMLElement, Document, etc.

import "@microsoft/fast-ssr/install-dom-shim";

Alternatively, a full DOM implementation such as jsdom or happy-dom can be used.

Construct the Renderer

Import the renderer factory and construct a TemplateRenderer. You will also need a RenderInfo object. A default is provided, more on this here.

import fastSSR from "@microsoft/fast-ssr";

const { templateRenderer, defaultRenderInfo } = fastSSR();

Define Custom Elements

Ensure that the custom elements used in the template you are rendering are defined in the customElements registry. This example defines a component directly, but you can also import any components being used:

import { customElement, html, FASTElement } from "@microsoft/fast-element":

@customElement({name: "my-element", template: html`<h1>${x => x.message}</h1>`})
class MyElement extends FASTElement {
    @attr
    public message = "Hello World";
}

Rendering

With the TemplateRenderer created and a custom element defined, the TemplateRenderer can now render a template with that element. The result will be an iterableIterator<string>, which allows the result to be streamed to the client before the entire template has been rendered.

const result = templateRenderer.render(html`
    <!DOCTYPE HTML>
    <html>
        <body>
            <my-element></my-element>
        </body>
    </html>
`, defaultRenderInfo);

The template being rendered can also be a fragment of HTML, it does not need to be a valid document:

const result = templateRenderer.render(html`<my-element></my-element>`, defaultRenderInfo);

Rendering Strings

The template renderer can also render string types just as it would a template:

const result = templateRenderer.render("<!DOCTYPE HTML><html><body><my-element></my-element></body></html>", defaultRenderInfo);

Rendering Templates with Bindings

A template can be rendered with arbitrary source data by providing that source as the third argument to .render(). When doing so, bindings are invoked with that source data:

const result = templateRenderer.render(html`
    <h1>${x => x.message}</h1>
`, defaultRenderInfo, { message: "hello world" });

Rendering Templates with Directives

The TemplateRenderer can render templates with directives such as when and repeat. Some directives are no-ops, see the directive support matrix for details.

import { when, repeat } from "@microsoft/fast-element";

const result = templateRenderer.render(html`
    ${when(x => x.shouldRender, html`
        <h1>Colors of a pixel</h1>
        ${repeat(x => x.data, html`<li>${color => color}</li>`)}
    `)}
`, defaultRenderInfo, { shouldRender: true, data: ["red", "green", "blue"] });
Directive Support Matrix
Directive Name Support
children
ref
repeat
slotted
when

Unsupported directives are no-ops. To understand more about why, see the Design Philosophy.

Configuring the RenderInfo Object

TemplateRenderer.render() must be invoked with a RenderInfo object. Its purpose is to provide different element renderers to the process, as well as metadata about the rendering process. It can be used to render custom elements from different templating libraries in the same process. A pre-generated object is created for you by the factory function, but you can also easily construct your own:

const { templateRenderer, elementRenderer } = fastSSR();
templateRenderer.render(html`<some-fast-element></some-fast-element>`, {
    elementRenderers: [elementRenderer],
    customElementHostStack: [],
    customElementInstanceStack: [],
});

To render elements built with another library, that library will need to provide an ElementRenderer for the library. For example, to render a Lit element along-side a FAST element, provide the FAST ElementRenderer and the Lit ElementRenderer to the RenderInfo object:

import fastSSR from "@microsoft/fast-ssr";
import { html } from "@microsoft/fast-element";
import { LitElementRenderer } from "@lit-labs/ssr/lib/lit-element-renderer.js"

const { templateRenderer, elementRenderer } = fastSSR();
// Some implementation that defines both FAST and Lit components
defineComponents();

const result = templateRenderer.render(html`
    <my-fast-element></my-fast-element>
    <my-lit-element></my-lit-element>
`, {
    elementRenderers: [elementRenderer, LitElementRenderer],
    customElementHostStack: [],
    customElementInstanceStack: []
});

Readme

Keywords

none

Package Sidebar

Install

npm i @microsoft/fast-ssr

Weekly Downloads

204

Version

1.0.0-beta.2

License

MIT

Unpacked Size

263 kB

Total Files

49

Last publish

Collaborators

  • eisenbergeffect
  • nirice
  • microsoft1es
  • chrisdholt
  • awentzel