Skip to content
Built with

Pages adapters ​

SDK Reference

Framework adapters for Pages Routing. Each adapter gives you a Vite plugin and a client runtime for one UI framework.

On this pagePick the adapter for Vue, React, Svelte or Solid · See each adapter's options · Check what each runtime exports

@void/vue ​

voidVue(options?) ​

Imported from "@void/vue/plugin". It returns an array of Vite plugins that handle Vue SFC compilation and SSR or hydration entry generation. It already includes @vitejs/plugin-vue. You do not need to install or configure it separately.

ts
import { voidVue } from '@void/vue/plugin';

export default defineConfig({
  plugins: [voidPlugin(), voidVue()],
});

Signature:

ts
function voidVue(options?: VoidVueOptions): Plugin[];

Options:

ts
interface VoidVueOptions {
  vue?: VuePluginOptions; // passed through to @vitejs/plugin-vue
  viewTransitions?: boolean; // enable View Transitions API for navigations
  prefetch?: {
    hoverDelay?: number;
    cacheFor?: number | string | [string, string];
  };
}

Vue Runtime ​

Imported from "@void/vue".

ExportDescription
LinkVue component for SPA navigation. Renders <a> for GET, <button> for non-GET methods. Props: href, method, data, prefetch, cacheFor, preserveScroll, preserveState, replace, reloadDocument, viewTransition, onNavigate.
useRouter()Returns the Void Router with current route state (url, path, query, params) and navigation methods: visit, refresh, awaitable prefetch, flush, flushAll.
useParams()Returns dynamic route params for the page currently being rendered.
useNavigation()Returns pending navigation state: { state, location, method }, where state is "idle", "loading", or "submitting" and location is the pending destination.
useForm(url, defaults, options?)Typed reactive form helper bound to a page action URL. Returns { data, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }.
useIslandForm(defaults)Form helper for island components. Same form state as useForm(), plus submit(url, method). post(url), put(url), patch(url), and delete(url) take the action URL and submit with fetch().
action(url, options?)Awaitable one-shot page action helper. Uses POST by default and accepts { data, method, params }, where method can be "PUT", "PATCH", or "DELETE". Returns an ActionResult.
useShared()Returns shared data injected by middleware via c.set("shared", {...}).

Vue Link merges GET data into the href query string. Primitive values use String(value). Arrays become repeated keys. null and undefined are left out. Nested objects throw. prefetch and reloadDocument only work with GET and throw on mutation links.

Vue GET navigation remounts the page. useForm() then picks up the new record's URL and defaults. Layouts stay mounted. Mutations and router.refresh() keep page state by default. Set preserveState to change this for navigation within the same record.

@void/react ​

voidReact(options?) ​

Imported from "@void/react/plugin". It returns an array of Vite plugins that handle SSR and hydration entry generation. It already includes @vitejs/plugin-react. You do not need to install or configure it separately.

ts
import { voidReact } from '@void/react/plugin';

export default defineConfig({
  plugins: [voidPlugin(), voidReact()],
});

Signature:

ts
function voidReact(options?: VoidReactOptions): Plugin[];

Options:

ts
interface VoidReactOptions {
  react?: ReactPluginOptions; // passed through to @vitejs/plugin-react
  viewTransitions?: boolean; // enable View Transitions API for navigations
  prefetch?: {
    hoverDelay?: number;
    cacheFor?: number | string | [string, string];
  };
}

React Runtime ​

Imported from "@void/react".

ExportDescription
LinkReact component for SPA navigation. Renders <a> for GET, <button> for non-GET methods. Props: href, method, data, prefetch, cacheFor, preserveScroll, preserveState, replace, reloadDocument, viewTransition, onNavigate.
useRouter()Returns the Void Router with current route state (url, path, query, params) and navigation methods: visit, refresh, awaitable prefetch, flush, flushAll. React navigations are scheduled as transitions.
useParams()Returns dynamic route params for the page currently being rendered.
useNavigation()Returns pending navigation state: { state, location, method }, where state is "idle", "loading", or "submitting" and location is the pending destination.
useForm(url, defaults, options?)Form helper hook. Returns { data, setData, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }.
useIslandForm(defaults)Form helper hook for island components. Same form state as useForm(). post(url), put(url), patch(url), and delete(url) take the action URL and submit with fetch().
action(url, options?)Awaitable one-shot page action helper. Uses POST by default and accepts { data, method, params }, where method can be "PUT", "PATCH", or "DELETE". Returns an ActionResult.
useShared()Returns shared data injected by middleware via c.set("shared", {...}).
Deferred<T>React-only prop type for defer() results. It is Promise<T> and is consumed with React use().

React Link merges GET data into the href query string. Primitive values use String(value). Arrays become repeated keys. null and undefined are left out. Nested objects throw. prefetch and reloadDocument only work with GET and throw on mutation links.

Deferred props from defer() are Suspense resources in React. Read them with React's use() inside a <Suspense> boundary. React Pages needs React 19. It uses streaming SSR for the first deferred shell. Rejections throw from use(). Use a normal React error boundary for custom error UI. Vue, Svelte and Solid keep the { loading, value, error } state object. To annotate props yourself, import Deferred from your adapter package: @void/react, @void/vue, @void/svelte or @void/solid. The type then matches that adapter's client runtime.

@void/svelte ​

voidSvelte(options?) ​

Imported from "@void/svelte/plugin". It returns an array of Vite plugins that handle SSR and hydration entry generation for Svelte 5. It already includes @sveltejs/vite-plugin-svelte. You do not need to install or configure it separately.

ts
import { voidSvelte } from '@void/svelte/plugin';

export default defineConfig({
  plugins: [voidPlugin(), voidSvelte()],
});

Signature:

ts
function voidSvelte(options?: VoidSvelteOptions): Plugin[];

Options:

ts
interface VoidSvelteOptions {
  svelte?: SveltePluginOptions; // passed through to @sveltejs/vite-plugin-svelte
  viewTransitions?: boolean; // enable View Transitions API
  prefetch?: {
    hoverDelay?: number;
    cacheFor?: number | string | [string, string];
  };
}

Svelte Runtime ​

Imported from "@void/svelte".

ExportDescription
LinkSvelte component for SPA navigation. Renders <a> for GET, <button> for non-GET methods. Props: href, method, data, prefetch, cacheFor, preserveScroll, preserveState, replace, reloadDocument, viewTransition, onNavigate.
useForm(url, defaults, options?)Form helper using Svelte 5 runes. Returns { data, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }.
useIslandForm(defaults)Form helper for island components. Same form state as useForm(), plus submit(url, method). post(url), put(url), patch(url), and delete(url) take the action URL and submit with fetch().
action(url, options?)Awaitable one-shot page action helper. Uses POST by default and accepts { data, method, params }, where method can be "PUT", "PATCH", or "DELETE". Returns an ActionResult.
useShared()Returns shared data injected by middleware via c.set("shared", {...}).
useRouter()Returns the Void Router with current route state (url, path, query, params) and navigation methods: visit, refresh, awaitable prefetch, flush, flushAll.
useParams()Returns dynamic route params for the page currently being rendered.
useNavigation()Returns pending navigation state: { state, location, method }, where state is "idle", "loading", or "submitting" and location is the pending destination.

Svelte Link merges GET data into the href query string. Primitive values use String(value). Arrays become repeated keys. null and undefined are left out. Nested objects throw. prefetch and reloadDocument only work with GET and throw on mutation links.

@void/solid ​

voidSolid(options?) ​

Imported from "@void/solid/plugin". It returns an array of Vite plugins that handle SSR and hydration entry generation for Solid. It already includes vite-plugin-solid. You do not need to install or configure it separately.

ts
import { voidSolid } from '@void/solid/plugin';

export default defineConfig({
  plugins: [voidPlugin(), voidSolid()],
});

Signature:

ts
function voidSolid(options?: VoidSolidOptions): Plugin[];

Options:

ts
interface VoidSolidOptions {
  solid?: SolidPluginOptions; // passed through to vite-plugin-solid
  viewTransitions?: boolean; // enable View Transitions API
  prefetch?: {
    hoverDelay?: number;
    cacheFor?: number | string | [string, string];
  };
}

Solid Runtime ​

Imported from "@void/solid".

ExportDescription
LinkSolid component for SPA navigation. Renders <a> for GET, <button> for non-GET methods. Props: href, method, data, prefetch, cacheFor, preserveScroll, preserveState, replace, reloadDocument, viewTransition, onNavigate.
useForm(url, defaults, options?)Form helper using Solid stores. Returns { data, setData, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }.
useIslandForm(defaults)Form helper for island components. Same form state as useForm(). post(url), put(url), patch(url), and delete(url) take the action URL and submit with fetch().
action(url, options?)Awaitable one-shot page action helper. Uses POST by default and accepts { data, method, params }, where method can be "PUT", "PATCH", or "DELETE". Returns an ActionResult.
useShared()Returns shared data injected by middleware via c.set("shared", {...}).
useRouter()Returns the Void Router with current route state (url, path, query, params) and navigation methods: visit, refresh, awaitable prefetch, flush, flushAll.
useParams()Returns dynamic route params for the page currently being rendered.
useNavigation()Returns pending navigation state: { state, location, method }, where state is "idle", "loading", or "submitting" and location is the pending destination.

Solid Link merges GET data into the href query string. Primitive values use String(value). Arrays become repeated keys. null and undefined are left out. Nested objects throw. prefetch and reloadDocument only work with GET and throw on mutation links.

Solid re-creates the page on GET navigation and when the route or its params change. useForm() then picks up the new record's URL and defaults. Layouts stay mounted.

Within the same record, back, forward, mutations and router.refresh() keep the page. They update its props in place, and so do resolved deferred props. Read props inside JSX or memos. Do not copy them in the component body. Set preserveState to change this for navigation within the same record.

Markdown Package ​

The optional @void/md package adds Markdown pages to Pages Routing. Install it with a Pages adapter. Then add voidMarkdown() to your Vite plugins.

ts
import { voidMarkdown } from '@void/md/plugin';

export default defineConfig({
  plugins: [voidPlugin(), voidReact(), voidMarkdown()],
});
Import pathContents
@void/md/pluginvoidMarkdown(options?), MarkdownOptions, MdPage
@void/mduseFrontmatter(), MdPage
@void/md/pagesGenerated metadata for Markdown pages, used for navigation, sidebars, and search indexes
@void/md/theme.cssFull Markdown theme styles
@void/md/theme-content.cssContent-only Markdown styles for apps that provide their own shell/layout

FrontmatterContext and setFrontmatter() are deprecated. Use useFrontmatter().

See Markdown Pages for setup and examples for each framework.

Form ​

Each Pages adapter exports Form. Pass the object from useForm() as form. method defaults to post. Form shows validation and action errors and keeps controlled input. It respects known quota retry deadlines and never resubmits on its own. renderError changes how action errors look. Svelte uses a snippet for this. See Actions and Forms.

Next steps ​

implemented.stream AI