Server Side Rendering

Markup can run on the server with the right setup. This means that you can render things on the server and send to the client.

Take for example this simple page created with Markup.

// ./server/pages/home.page.ts

import {html} from "@beforesemicolon/markup";

interface HomePageProps {
  title: string;
}

export const HomePage = ({title}: HomePageProps) => {
  return html`
    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>${title}</title>
      </head>
      <body>
        <h1>Hello World</h1>
      </body>
    </html>
 `
}

We can then have a simple express server to render everything.

// ./server/app.ts

import express, {Request, Response} from 'express';
import path from "path";

export const app = express();

app.use(express.static(path.resolve(__dirname, 'public')))

We can then render the page as so:

// ./server/app.ts

import {HomePage} from "./public/home.page.ts";
import {toStatic} from "./to-static.ts";

app.get('/', (_req: Request, res: Response) => {
  res.send(toStatic(HomePage({
    title: 'Welcome To The Page'
  })))
})

In the above example you can see the toStatic helper function. This is something you can easily create to convert HTMLTemplate into HTML string that we can send to the client.

The toStatic implementation looks like so:

// ./server/to-static.ts

import 'global-jsdom/register'
import {HtmlTemplate} from "@beforesemicolon/markup";

export const toStatic = (temp: HtmlTemplate, docType = '<!doctype html>') => {
  document.body.innerHTML = ''
  temp.render(document.body)
  return docType + document.body.innerHTML.trim()
}

Notice that there is a global-jsdom package and all it does is make DOM APIs global that Markup can use to function normally.

This is a simple example on how to approach rendering things on the server. The main requirement is to have some type of DOM API that can render on the server environment you use (Deno, Bun, Node, etc). From there, making such APIs globally available will cover everything, and you can use Markup freely.

Try it Out