npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@lit-labs/ssr-react

v0.3.0

Published

Lit SSR integration for React

Downloads

3,144

Readme

@lit-labs/ssr-react

A package for integrating Lit SSR with React and React frameworks.

Overview

By default, React's SSR library renders custom elements shallowly, i.e. only the element's open and closing tags, attributes, and light DOM children are present in the server-rendered HTML - shadow DOM contents are not rendered.

This package provides tools to integrate @lit-labs/ssr with React SSR so that Lit components are deeply rendered, including their shadow DOM contents.

Usage

To get React SSR to deeply render Lit components, we'll need React JSX code to call an enhanced version of createElement() provided by this package. The way to achieve this depends on your project configuration.

Monkey patching React element creation (recommended)

This package provides the @lit-labs/ssr-react/enable-lit-ssr.js module which, when imported in a server environment, has the side-effect of monkey patching React.createElement() and runtime JSX functions to be enhanced to add the declarative shadow DOM output to registered custom elements. This can be imported at the entry point of the application before React is imported or any JSX containing Lit components is evaluated.

// index.js
import '@lit-labs/ssr-react/enable-lit-ssr.js';

import React from 'react';
import ReactDOM from 'react-dom';
import './my-element.js';

const App = () => {
  return <my-element />;
};

In the browser environment, this module does not patch React.createElement() but instead imports @lit-labs/ssr-client/lit-element-hydrate-support.js which must be imported before the lit package to allow hydration of server-rendered Lit elements.

Using the Classic Runtime JSX Transform

The classic JSX transform replaces JSX expressions with React.createElement() function calls. In the default mode, it requires that React is imported and available in the scope of the JSX file.

If you wish to control which components use the enhanced createElement() function without a global monkey patch, you may do so by using a JSX pragma.

- import React from 'react';
+ /** @jsx createElement */
+ import {createElement} from '@lit-labs/ssr-react';

const Component = (props) => {
  return <my-element />;
}

You may also set the compiler options to specify the function to use instead of the JSX pragma.

  • For Babel: set the pragma option for @babel/preset-react to "createElement".
  • For TypeScript: set the jsxFactory option in tsconfig.json to "createElement".

Note that the import line must still be present for every file that contains JSX expressions to transform in the classic runtime mode.

This approach only works for server-rendering custom elements added to your project's JSX expressions. It will not affect any pre-compiled JSX expressions or direct calls to React.createElement(). You will also need to manually import the @lit-labs/ssr-client/lit-element-hydrate-support.js to your client JS. For those scenarios, use the monkey patching approach.

Using the Automatic Runtime JSX Transform

If your project is using the runtime JSX transform, this package can serve as the JSX import source.

  • For Babel: set the importSource option in @babel/preset-react to @lit-labs/ssr-react.
  • For TypeScript: set the jsxImportSource option in tsconfig.json to @lit-labs/ssr-react.

These JSX runtime modules contain jsx functions enhanced to add the declarative shadow DOM output to registered custom elements when imported into server environemtns. They also automatically import @lit-labs/ssr-client/lit-element-hydrate-support.js in the browser environment.

This method will not work for any pre-compiled JSX expressions or direct calls to React.createElement(), including those in the usage of the @lit/react package's createComponent(). Consider using the monkey patching approach to handle such scenarios.

Advanced Usage

For composing multiple createElement() functions, e.g. for use along side other React libraries that enhancee createElement(), this package also provides a wrapCreateElement() function which accepts a createElement() function and returns an enhanced one.

import {wrapCreateElement} from '@lit-labs/ssr-react';
import React from 'react';

const enhancedCreateElement = wrapCreateElement(React.createElement);

How it Works

The enhancements to React.createElement() or runtime JSX functions work by adding a <template shadowrootmode> element to the custom element's children list, if the custom element is defined and has a Lit SSR ElementRenderer registered to SSR the element. By default, all LitElement subclasses are rendered by the built-in LitElementRenderer.

Handling of Props

For bare custom elements, all props provided by React are set as attributes on the element during server rendering, as is the default behavior for custom elements rendered by React on the client (as of version 18). This works for simple components whose properties can easily be represented as attributes, i.e. they are easily serialized/deserialized and the attribute name does not differ with the property name.

For Lit elements wrapped with @lit/react's createComponent(), properties present on the element will be set as properties instead of attributes for server rendering. Client side hydration will also be deferred such that it'll wait for element properties to be set before the first update happens.

Enabling Declarative Shadow DOM

As of February 2023, declarative shadow DOM is supported in Chromium and Safari Technology Preview. For browsers that do not yet support it, you must include the template-shadowroot polyfill. Without this, React's own hydration may warn of hydration mismatch due to the lingering <template> element. See https://lit.dev/docs/ssr/client-usage/#using-the-template-shadowroot-polyfill for inspiration on how to incorporate this into your application.

Contributing

Please see CONTRIBUTING.md.