Host JSX file as a web page

Like serving static files, JSX files can also be served as a web page.

serveJsx is built-in middleware to serve JSX files. It is similar to serveStatic but It uses dynamic import to build a response based on JSX file.

// Copyright 2019 Yusuke Sakurai. All rights reserved. MIT license.
import { createRouter } from "https://servestjs.org/@v0.30.0/router.ts";
import { serveJsx } from "https://servestjs.org/@v0.30.0/serve_jsx.ts";
const router = createRouter();
// .jsx/.tsx files in ./pages directory will be dynamically imported
// and rendered component served as html
router.use(serveJsx("./pages", f => import(f)));
router.listen(":8899");

Here is a typical directory structure for using serveJsx along with serveStatic.

.
├── main.ts
├── pages
│   ├── about.tsx
│   └── index.tsx
└── public
    └── index.css

JSX files that served as a page must export React component as default. If component needs asynchronous initialization for rendering in server side, you should define getInitialProps to the component.

It is async function that returns Promise of property type of the component. This methodology is similar to Next.js but totally different. Component will be rendered only on the server side and won't be hydrated on the client side.

// @deno-types="https://servestjs.org/@v0.30.0/types/react/index.d.ts"
import React from "https://dev.jspm.io/react/index.js";
import { DFC } from "https://servestjs.org/@v0.30.0/jsx.ts";

const Index: DFC<{ title: string; text: string }> = ({ title, text }) => {
  return (
    <html>
      <head>
        <meta charSet={"UTF-8"} />
        <title>{title}</title>
      </head>
      <body>
        <div>{text}</div>
      </body>
    </html>
  );
};

// getInitialProps is an asynchronous data fetcher
// for rendering components in server side.
// This is identical methodology to Next.js
// It will be called exactly once for each request.
Index.getInitialProps = async () => {
  const resp = await fetch("https://some-api.com");
  const text = await resp.text();
  return { title: "Index Page", text };
};

// default export are used for Server Side Rendering.
export default Index;