JSX Preact

Create pages and layouts with JSX (Preact).

Options See on deno.land

extensions string[]

The list of extensions this plugin applies to

Default:
[ ".jsx", ".tsx" ]
pageSubExtension string

Optional sub-extension for page files

includes string

Custom includes path

Default:
site.options.includes

Description

This plugin works exactly like JSX but using Preact (a 3kb React alternative with the same API but faster and lighter) to render the JSX.

Note that this plugin only provides JSX support to generate the pages at building time. This means that client-side properties like onClick won't work. If you want to use React for creating code for the browser (like SPAs), use the ESbuild plugin.

Installation

Import this plugin in your _config.ts file to use it:

import lume from "lume/mod.ts";
import jsx from "lume/plugins/jsx_preact.ts";

const site = lume();

site.use(jsx(/* Options */));

export default site;

Configuration

You might want to add the following compilerOptions to deno.json in order to configure the JSX transform:

{
  // ...
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "npm:preact"
  }
}

Tip

Go to Using TypeScript for more info about using TypeScript with Lume.

Creating pages

To create a page with this format, just add a file with .jsx or .tsx extension to your site. This format works exactly the same as JavaScript/TypeScript files, but with the addition of the ability to export JSX code in the default export:

export const title = "Welcome to my page";
export const layout = "layouts/main.vto";

export default (data: Lume.Data, helpers: Lume.Helpers) => (
  <>
    <h1>{data.title}</h1>
    <p>This is my first post using lume. I hope you like it!</p>
  </>
);

Note that this page uses the layouts/main.vto Vento layout to wrap the content. (You can mix different template languages like Nunjucks and JSX.)

Creating layouts

To create layouts in JSX, just add .jsx or .tsx files to the _includes directory. Note that we need to use the variable children to render the page content instead of content. The difference is that content is a string and cannot be easily used in JSX because it's escaped, and children is the JSX object un-rendered.

export default ({ title, children }: Lume.Data, helpers: Lume.Helpers) => (
  <html>
    <head>
      <title>{title}</title>
    </head>
    <body>
      {children}
    </body>
  </html>
);

Tip

Lume will automatically add the missing <!DOCTYPE html> to the generated .html pages.

Components

You can create Lume components in JSX creating files in the _components folder. For example:

export default function ({ children }) {
  return (
    <button className="my-button">
      {children}
    </button>
  );
}

To render the component in your templates use the comp variable:

export default function ({ comp }) {
  return (<comp.Button>Click me!</comp.Button>);
}

Important

Importing a component with import Button from "./_components/button.ts" doesn't work for live-reloading due a limitation of Deno that cannot update any imported module without restarting the entire process. So it's highly recomendable to use the comp variable to consume components and mitigate this limitation.