On demand

Plugin to render pages on demand in Deno Deploy

Description

This plugin allows to render pages on demand. It can be useful in some scenarios:

  • There are pages with dynamic content that must be generated at the request time.
  • The site is too big, with thousands of pages, so the build takes too much time.

Lume can generate pages on demand for these cases.

Note: This plugin only works with Deno Deploy.

Installation

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

import lume from "lume/mod.ts";
import onDemand from "lume/plugins/on_demand.ts";

const site = lume();

site.use(onDemand());

export default site;

See all available options in Deno Doc.

How does it work?

First, you need to configure the pages that must be rendered on demand. This is done by setting the ondemand variable to true. For example, let's say we want to render the home page dynamically:

---
layout: layout.njk
title: This is a title
ondemand: true
---

<h1>{{ title }}</h1>

When the site is built, this page will be skipped. But a _routes.json file will be generated containing a map with the URL and the associated page file:

{
  "/": "./index.njk"
}

Finally, in the serve.ts file used by Deno Deploy, we have to import and use the onDemand middleware:

import site from "./_config.ts";
import Server from "lume/core/server.ts";
import onDemand from "lume/middlewares/on_demand.ts";

const server = new Server({
  port: 8000,
  root: site.dest(),
});

server.use(onDemand({ site }));

server.start();

console.log("Listening on http://localhost:8000");

The middleware needs an instance of our site in order to render the pages. We can import it from the _config.ts file. It also automatically loads the _routes.json file in order to know which file needs to be rendered for each URL. If the file is in a different path, you can configure it.

And that's all! The _routes.json file is regenerated automatically by the build to ensure it's up to date with your changes.

Preload modules

Deno Deploy doesn't have support for dynamic imports (modules imported dynamically with import("./module-name.ts")). See this issue for more info.

If you have on-demand pages created with JavaScript or TypeScript, the plugin generates not only a _routes.json file, but also a _preload.ts file. This file contains the code to preload statically all modules needed to build the pages on demand. You have to import it in your server.ts so Lume can render these pages in Deno Deploy:

import site from "./_config.ts";
import Server from "lume/core/server.ts";
import onDemand from "lume/middlewares/on_demand.ts";
import preload from "./_preload.ts";

const server = new Server({
  port: 8000,
  root: site.dest(),
});

// Preload the JS/TS modules
preload(site);

server.use(onDemand({ site }));

server.start();

console.log("Listening on http://localhost:8000");

See an example

You can see a live example of a site with two pages generated on demand. And the repository with the source code.