domco

Tutorial

The following documentation covers the basics of creating a site and all of the features domco provides in addition to Vite and Hono. See the Vite or Hono documentation for more information and configuration options.

Create a new project

To get started, you’ll need to have Node, Bun, or Deno or installed on your computer. Then run the create-domco script to create a new project. If you already have an existing client-side Vite project check out the migration instructions.

Node

npm create domco@latest

Bun

bun create domco@latest

Deno

deno run -A npm:create-domco@latest

Entry Points

domco identifies the entry points of your application by file name. These entry points are prefixed with + so they are easily identifiable.

+app

The app entry point is located in within src/server/, this is the server entry point for your application.

.
└── src/
	└── server/
		└── +app.(js,ts,jsx,tsx)

+app modules export a handler function that takes in a Request, and returns a Response.

// src/server/+app.ts
export const handler = async (req: Request) => {
	return new Response("Hello world");
};

From here, it’s up to you. For example, you could route different requests to different responses, based on the req.url.

// src/server/+app.ts
export const handler = async (req: Request) => {
	const { pathname } = new URL(req.url);

	if (pathname === "/") {
		return new Response("Hello");
	} else if (pathname === "/world") {
		return new Response("World");
	}

	return new Response("Not found", { status: 404 });
};

Or add a framework like Hono to do your routing and more!

+page

To create a page, add +page.html file in a directory within src/client/.

domco configures Vite to process each +page.html as a separate entry point automatically. Everything linked in these pages will be bundled and included in the output upon running vite build. You can serve the transformed contents of a page via the client:page virtual module.

.
└── src/
	├── client/
	│	└── +page.html
	└── server/
		└── +app.ts

+script

Each +script.(js,ts,jsx,tsx) file within src/client/ will be processed as an entry point by Vite. Client-side scripts can be used in pages via a script tag, or on the server without a page by using the client:script virtual module.

.
└── src/
	├── client/
	│	└── +script.ts
	└── server/
		└── +app.ts

Virtual Modules

domco provides a doorway to the client via virtual modules. These allow you to not have to worry about getting the hashed filenames for client assets after the build is complete. You can easily serve a +page or include the tags for a +script in a response.

client:page

You can import the transformed HTML of any +page.html from this module or one of it’s sub-paths.

// returns transformed content of `src/client/+page.html`
import { html } from "client:page";
// `src/client/other/+page.html`
import { html as otherHtml } from "client:page/other";

export const handler = async (req: Request) => {
	return new Response(
		html, // Your Vite app.
		{
			headers: { "Content-Type": "text/html" },
		},
	);
};

client:script

You can also easily get the tags for any +script file on the server as well. These script tags (including all imports) can be accessed via the client:script virtual module. They can be included in an HTML string, or inside of JSX.

// returns transformed content of `src/client/+script.ts`
import { tags } from "client:script";
// `src/client/other/+script.ts`
import { tags as otherTags } from "client:script/other";

export const handler = async (req: Request) => {
	return new Response(
		`<!doctype html>
		<html lang="en">
			<head>
				<meta charset="UTF-8" />
				<meta name="viewport" content="width=device-width, initial-scale=1.0" />
				${tags}
				<title>Document</title>
			</head>
			...
		</html>`,
		{
			headers: { "Content-Type": "text/html" },
		},
	);
};

In development, domco links the scripts to the source. In production, domco reads the manifest generated by the client build and includes the hashed version of these file names and their imports in production.

Prerender

Export a prerender variable to prerender routes that respond with HTML.

// src/server/+app.ts
export const prerender = ["/", "/post-1", "/post-2"];

After the Vite build is complete, domco will import your production app and request the routes provided. The responses will be written into dist/client/(prerender-path)/index.html files upon build.

If you are using an adapter, these static files will be served in front of your request handler. So when an index.html file is found for the route, it is served directly without hitting your handler.

That’s It!

domco has a minimal API surface area and tries to get out of your way during development.

Next, learn how to deploy your application.

Edit this page