Dark renderer for server
npm install @dark-engine/platform-server
npx degit github:atellmer/dark/templates/server app
`
`
cd app
npm i
npm run frontend
npm start
`
npm:
`
npm install @dark-engine/core @dark-engine/platform-browser @dark-engine/platform-server
`
yarn:
`
yarn add @dark-engine/core @dark-engine/platform-browser @dark-engine/platform-server
`
API
`tsx
import {
renderToString,
renderToStream,
VERSION,
} from '@dark-engine/platform-server';
`
Usage
Suppose you have a directory like this:
`
app/
ββ frontend/
β ββ static/
β β ββ build.js
β ββ app.tsx
β ββ index.tsx
β ββ webpack.config.js
ββ backend/
β ββ app.ts
ββ package.json
ββ tsconfig.json
`
Rendering to string
The method renders app to string async to unblock main thread of Node.js
`tsx
// backend/app.ts
import { renderToString } from '@dark-engine/platform-server';
import { Page, App } from '../frontend/app';
server.use(express.static(join(__dirname, '../frontend/static')));
server.get('*', async (req, res) => {
const content = Page({ title: 'Awesome App', slot: App() });
const app = await renderToString(content);
const page = ${app};
res.statusCode = 200;
res.send(page);
});
`
`tsx
// frontend/app.tsx
import { component } from '@dark-engine/core';
const Page = component(({ title, slot }) => {
return (
{title}
{slot}
);
})
const App = component(() => Hello World);
export { Page, App };
`
`tsx
// frontend/index.tsx
import { hydrateRoot } from '@dark-engine/platform-browser';
import { App } from './app';
hydrateRoot(document.getElementById('root'), );
`
Rendering to stream
Dark can render to readable streams, i.e. give chunks of data as quickly as possible when starting rendering. This method works better for some Lighthouse metrics.
`tsx
import { renderToStream } from '@dark-engine/platform-server';
server.get('*', (req, res) => {
const content = Page({ title: 'Awesome App', slot: App() });
const stream = renderToStream(content);
res.statusCode = 200;
stream.pipe(res);
});
`
Please see code examples in the /examples directory.
If you are using Metatags component from @dark-engine/platform-browser, you should use option awaitMetatags when you are rendering to stream.
`tsx
const stream = renderToStream(content, { awaitMetatags: true });
`
Lazy modules
Dark is designed to fully support asynchronous lazy code modules during the server-side rendering process. When Dark encounters a lazy module that isnβt yet cached, it halts the rendering process and waits for the module to load and cache before resuming from where it left off. In subsequent renderings, all modules are retrieved from the cache.
This ensures that all lazy modules are fully loaded and the user receives the complete content. If the rendering occurs on the client-side, the lazy module is handled through the Suspense` component, which displays a spinner or skeleton screen during loading.