Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/docs/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import DeferAndActivity from "./pages/learn/DeferAndActivity.mdx";
import FileSystemRouting from "./pages/learn/FileSystemRouting.mdx";
import MultipleEntrypoints from "./pages/advanced/MultipleEntrypoints.mdx";
import SSR from "./pages/advanced/SSR.mdx";
import BuildEntryApi from "./pages/api/BuildEntry.mdx";
import EntryDefinitionApi from "./pages/api/EntryDefinition.mdx";
import FAQ from "./pages/FAQ.mdx";
import GettingStarted from "./pages/GettingStarted.mdx";
Expand Down Expand Up @@ -65,6 +66,12 @@ export const routes: RouteDefinition[] = [
path: "/api/defer",
component: <Layout>{defer(<DeferApi />, { name: "DeferApi" })}</Layout>,
}),
route({
path: "/api/build-entry",
component: (
<Layout>{defer(<BuildEntryApi />, { name: "BuildEntryApi" })}</Layout>
),
}),
route({
path: "/api/entry-definition",
component: (
Expand Down
4 changes: 4 additions & 0 deletions packages/docs/src/components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ export const navigation: NavSection[] = [
href: "/api/funstack-static",
},
{ label: "defer()", href: "/api/defer" },
{
label: "BuildEntryFunction",
href: "/api/build-entry",
},
{
label: "EntryDefinition",
href: "/api/entry-definition",
Expand Down
108 changes: 108 additions & 0 deletions packages/docs/src/pages/api/BuildEntry.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# BuildEntryFunction

The `BuildEntryFunction` type defines a custom build entry point that lets you hook into the production build process. Use it to run additional work before, after, or in parallel with the default build.

## Import

```typescript
import type { BuildEntryFunction } from "@funstack/static/server";
```

## Usage

Create a module that default-exports a `BuildEntryFunction`, then reference it via the [`build`](/api/funstack-static#build-optional) option in your Vite config:

```typescript
// vite.config.ts
import funstackStatic from "@funstack/static";
import { defineConfig } from "vite";

export default defineConfig({
plugins: [
funstackStatic({
entries: "./src/entries.tsx",
build: "./src/build.ts",
}),
],
});
```

```typescript
// src/build.ts
import type { BuildEntryFunction } from "@funstack/static/server";

export default (async ({ build, outDir }) => {
// Run the default build
await build();
// ... do additional work after the build
}) satisfies BuildEntryFunction;
```

## Type Definition

```typescript
type BuildEntryFunction = (context: BuildEntryContext) => Promise<void> | void;

interface BuildEntryContext {
build: () => Promise<void>;
outDir: string;
}
```

## Context Properties

### build

**Type:** `() => Promise<void>`

Performs the default build flow (rendering entries and writing output files). You must call this function to produce the standard build output. You can run additional work before, after, or in parallel with it.

### outDir

**Type:** `string`

Absolute path to the output directory where built files are written. Use this to write additional files alongside the build output.

## Examples

### Generate a sitemap alongside the build

```typescript
import { writeFile } from "node:fs/promises";
import path from "node:path";
import type { BuildEntryFunction } from "@funstack/static/server";

export default (async ({ build, outDir }) => {
const sitemap = generateSitemap(); // your sitemap logic

await Promise.all([
build(),
writeFile(path.join(outDir, "sitemap.xml"), sitemap),
]);
}) satisfies BuildEntryFunction;
```

By running `build()` and `writeFile()` in parallel with `Promise.all`, the sitemap is generated without adding to the total build time.

### Run work before or after the build

```typescript
import type { BuildEntryFunction } from "@funstack/static/server";

export default (async ({ build }) => {
console.log("Build starting...");
await build();
console.log("Build complete!");
}) satisfies BuildEntryFunction;
```

## Notes

- The build entry module runs in the **RSC environment**, so you have access to Node.js APIs.
- The `build` option is only used during **production builds** (`vite build`), not in dev mode.
- If no `build` option is specified, the default build flow runs automatically.

## See Also

- [funstackStatic()](/api/funstack-static) - Plugin configuration (includes the `build` option)
- [Multiple Entrypoints](/advanced/multiple-entrypoints) - Multi-page static site generation
20 changes: 20 additions & 0 deletions packages/docs/src/pages/api/FunstackStatic.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,25 @@ Sentry.init({

**Note:** Errors in the client init module will propagate normally and prevent the app from rendering.

### build (optional)

**Type:** `string`

Path to a module that customizes the production build process. The module should `export default` a function that receives a `BuildEntryContext` with a `build` function (which performs the default build flow) and an `outDir` string (the output directory path).

This allows you to run additional work before, after, or in parallel with the build — for example, generating a sitemap or other static assets.

Only called during production builds (`vite build`), not in dev mode. The module runs in the RSC environment.

```typescript
funstackStatic({
entries: "./src/entries.tsx",
build: "./src/build.ts",
});
```

See [BuildEntryFunction](/api/build-entry) for the full type definition and examples.

### rscPayloadDir (optional)

**Type:** `string`
Expand Down Expand Up @@ -295,5 +314,6 @@ You can use the same Vite commands you would use in a normal Vite project:

- [Getting Started](/getting-started) - Quick start guide
- [Multiple Entrypoints](/advanced/multiple-entrypoints) - Multi-page static site generation
- [BuildEntryFunction](/api/build-entry) - Custom build entry point
- [defer()](/api/defer) - Deferred rendering for streaming
- [React Server Components](/learn/rsc) - Understanding RSC