Skip to content

Universal SSR engine and CLI with Vite integration for modern JavaScript frameworks

License

Notifications You must be signed in to change notification settings

codemonster-ru/ssr-service

Repository files navigation

@codemonster-ru/ssr-service

npm version Tests License

🚀 A universal SSR service for Annabel Framework and standalone use.

Allows you to render Vue (and potentially React, Svelte, Solid, etc.) components on the server (Server-Side Rendering) and use them in PHP applications via SSR Bridge or as a separate Node.js SSR service.

✨ Possibilities

  • Rendering Vue components (and other frameworks via Vite) on the server (Node.js).
  • POST /render API for getting the finished HTML.
  • Automatic HTML assembly:
    • Injects <script type="module"> for entry and chunks.
    • Injects <link rel="stylesheet"> for CSS.
    • Adds <link rel="modulepreload"> and <link rel="preload"> for JS, CSS, fonts, images (configurable).
  • Easy integration with PHP via Annabel\SSR\Bridge.
  • Can be run:
    • Locally inside Annabel Skeleton.
    • As a standalone server (Node.js, Docker, PM2, systemd).

📦 Installation

Global:

npm install -g @codemonster-ru/ssr-service

Or locally in the project:

npm install @codemonster-ru/ssr-service

🚀 Launch

Via CLI

ssr server

By default the service runs at http://localhost:3001.

Options:

ssr server --port 4000 --serverEntry ./dist/server/entry-server.js

Via Node.js (locally)

npx ssr server

In development mode (tsx/ts-node)

cross-env DEV_ROOT=./playgrounds/vue DEV_ENTRY_SERVER=./src/entry-server.ts tsx src/server.ts

In production

npm run build
npm start

🔧 Configuration

All parameters can be set via CLI, .env or directly via loadConfig.

Param Default Description
MODE production Development or production or test
CLI_MODE false To complete SSR correctly in CLI
CLIENT_PATH dist/client Path to client build (static files)
SERVER_ENTRY dist/server/entry-server.js Path to server entry (SSR build)
MANIFEST_PATH dist/client/manifest.json Path to manifest.json
DEV_ROOT Project root for dev-mode (where vite.config.ts is)
DEV_ENTRY_SERVER ./src/entry-server.ts Entry for dev SSR
PORT 3001 SSR server port
CLIENT_ENTRY /assets/entry-client.js Fallback client entry if no manifest.json
SCRIPT_ATTRS "" Attributes for all <script> tags (defer, async, crossorigin, etc.)
DISABLE_PRELOAD false Disable all preloads
DISABLE_JS_PRELOAD false Disable only JS preload
DISABLE_CSS_PRELOAD false Disable only CSS preload
DISABLE_FONT_PRELOAD false Disable only font preload
DISABLE_IMAGE_PRELOAD false Disable only image preload

🔗 Using with PHP (via Bridge)

// Local
$bridge = new \Annabel\SSR\Bridge('local');
$html = $bridge->render('<h1>{{ title }}</h1>', ['title' => 'Hello from PHP']);

// Remote
$bridge = new \Annabel\SSR\Bridge('http', 'http://127.0.0.1:3001');
$html = $bridge->render('<h1>{{ title }}</h1>', ['title' => 'Hello from PHP']);

📑 Example HTML Output

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Vue SSR playground</title>

        <meta name="description" content="Description of the page" />
        <meta property="og:title" content="Vue SSR playground" />

        <link rel="modulepreload" href="/assets/entry-client.abc.js" />
        <link rel="modulepreload" href="/assets/chunk-xyz.def.js" />
        <link rel="preload" as="style" href="/assets/style.css" />
        <link rel="preload" as="font" href="/assets/font.woff2" crossorigin />
        <link rel="preload" as="image" href="/assets/logo.png" />

        <link rel="stylesheet" href="/assets/style.css" />
        <link rel="stylesheet" href="/assets/chunk-xyz.css" />
    </head>
    <body>
        <div id="app"><!-- SSR HTML --></div>
        <script>
            window.__COMPONENT__ = 'App';
            window.__PROPS__ = { message: 'Hello' };
        </script>
        <script type="module" defer src="/assets/entry-client.abc.js"></script>
        <script type="module" defer src="/assets/chunk-xyz.def.js"></script>
    </body>
</html>

📖 Documentation

👨‍💻 Author

Kirill Kolesnikov

📜 License

MIT