Skip to content

Latest commit

 

History

History
318 lines (232 loc) · 41.1 KB

pages.md

File metadata and controls

318 lines (232 loc) · 41.1 KB
outline deep

Pages Adapters {#framework-adaptors}

Framework adaptors for Pages Routing. Each adaptor provides a Vite plugin and client-side runtime.

Navigation destinations {#navigation-destinations}

All four adapters support typed URLs through routeUrl(). Pass the returned string to Link's href, which has the type Href.

The router's visit(destination, options?), prefetch(destination, options?), and flush(destination, method?) accept RouteUrlInput: a string, URL, or typed destination object.

With routing.typedRoutes, href and router strings must match one of your routes, or be a same-page or external URL. Without it, both accept any string.

See Typed navigation for framework examples.

Prefetching {#prefetching}

Link's prefetch prop takes true, false, a strategy, or an array of strategies:

type LinkPrefetchStrategy = 'hover' | 'click' | 'mount' | 'visible';
Value Loads the page
'hover' or true When the pointer rests on the link for hoverDelay, when it gets keyboard focus, or on touch
'click' When the mouse button or finger goes down, just before the click
'mount' As soon as the link renders
'visible' Once the link has stayed in view for 300 ms. Links scrolled quickly past are skipped
false Never

With an array such as ['visible', 'hover'], the first strategy to happen loads the page, and later ones reuse it. prefetch works only on GET links, and links to other sites are never prefetched. No strategy prefetches while the browser reports data saver or a 2G connection, which only Chromium-based browsers report; calling router.prefetch() yourself still loads the page.

cacheFor sets how long a prefetched page is reused, in milliseconds or as a duration such as '5m'. A pair such as ['30s', '5m'] treats the page as fresh for 30 seconds, then still shows it for up to 5 minutes while loading a fresh copy in the background.

Each adapter plugin's prefetch option sets app-wide values:

Option Default Description
defaultStrategy false The prefetch value for every Link that doesn't set its own. A Link's own prefetch replaces it, and prefetch={false} turns it off. Links with a non-GET method or reloadDocument don't use it.
hoverDelay 75 Milliseconds the pointer rests on a link before 'hover' prefetches.
cacheFor '30s' The cacheFor value for every Link that doesn't set its own.

@void/vue {#void-vue}

voidVue(options?) {#voidvue-options}

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

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

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

Signature:

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

Options:

interface VoidVueOptions {
  vue?: VuePluginOptions; // passed through to @vitejs/plugin-vue
  viewTransitions?: boolean; // enable View Transitions API for navigations
  prefetch?: {
    defaultStrategy?: boolean | LinkPrefetchStrategy | LinkPrefetchStrategy[]; // default: false
    hoverDelay?: number; // default: 75 (ms)
    cacheFor?: number | string | [string, string]; // default: '30s'
  };
}

Vue Runtime {#vue-runtime}

Imported from "@void/vue".

Export Description
Link Vue component for SPA navigation. Renders <a> for GET, <button> for non-GET methods. Props: href, method, data, prefetch, cacheFor, preserveScroll, preserveState, replace, reloadDocument, viewTransition, activeMatch, onNavigate. Adds aria-current="page" and data-void-active to the link to the current page (active links), and data-void-pending to links to a page while it loads (pending links).
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. Pass the page's pattern as the type argument, such as useParams<'/users/:id'>(), to type them.
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, setError, 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, preserveScroll }, where method can be "PUT", "PATCH", or "DELETE". Returns an ActionResult.
isVoidActionError(error) Returns true when error is a VoidActionError at any status, such as a thrown 401, 403, or 500. Narrows error to VoidActionError. See handling thrown errors.
isCallSiteActionError(error) Returns true only for the expected VoidActionError statuses that action() returns, such as 409 or 422.
useShared() Returns shared data. Middleware sets it with c.set("shared", {...}); a loader or action can update it. See Shared data.

Vue Link GET data is merged into the rendered href query string. Primitive values are serialized with String(value), arrays become repeated keys, null and undefined are omitted, and nested objects throw. prefetch and reloadDocument are GET-only and throw for mutation links.

Vue GET navigation remounts the page so useForm() picks up the destination record's URL and defaults; layouts persist. Mutations and router.refresh() preserve page state by default. Set preserveState explicitly to override the default for navigation within the same record.

@void/react {#void-react}

voidReact(options?) {#voidreact-options}

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

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

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

Signature:

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

Options:

interface VoidReactOptions {
  react?: ReactPluginOptions; // passed through to @vitejs/plugin-react
  viewTransitions?: boolean; // enable View Transitions API for navigations
  prefetch?: {
    defaultStrategy?: boolean | LinkPrefetchStrategy | LinkPrefetchStrategy[]; // default: false
    hoverDelay?: number; // default: 75 (ms)
    cacheFor?: number | string | [string, string]; // default: '30s'
  };
}

React Runtime {#react-runtime}

Imported from "@void/react".

Export Description
Link React component for SPA navigation. Renders <a> for GET, <button> for non-GET methods. Props: href, method, data, prefetch, cacheFor, preserveScroll, preserveState, replace, reloadDocument, viewTransition, activeMatch, onNavigate. Adds aria-current="page" and data-void-active to the link to the current page (active links), and data-void-pending to links to a page while it loads (pending links).
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. Pass the page's pattern as the type argument, such as useParams<'/users/:id'>(), to type them.
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, setError, 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, preserveScroll }, where method can be "PUT", "PATCH", or "DELETE". Returns an ActionResult.
isVoidActionError(error) Returns true when error is a VoidActionError at any status, such as a thrown 401, 403, or 500. Narrows error to VoidActionError. See handling thrown errors.
isCallSiteActionError(error) Returns true only for the expected VoidActionError statuses that action() returns, such as 409 or 422.
useShared() Returns shared data. Middleware sets it with c.set("shared", {...}); a loader or action can update it. See Shared data.
Deferred<T> React-only prop type for defer() results. It is Promise<T> and is consumed with React use().

React Link GET data is merged into the rendered href query string. Primitive values are serialized with String(value), arrays become repeated keys, null and undefined are omitted, and nested objects throw. prefetch and reloadDocument are GET-only and throw for mutation links.

React useForm() accepts onSuccess?: () => void | Promise<void> and onError?: (error: Record<string, string> | VoidActionError) => void | Promise<void>. pending stays true until callbacks finish. See submission callbacks.

React deferred props returned from defer() are Suspense resources. Read them with React's use() inside a <Suspense> boundary. React Pages requires React 19 and uses streaming SSR for the initial deferred shell. Rejections throw from use(), so use a normal React error boundary for custom deferred error UI. Vue, Svelte, and Solid keep the { loading, value, error } deferred state object. When explicitly annotating props, import Deferred from the framework adapter package (@void/react, @void/vue, @void/svelte, or @void/solid) so the type matches that adapter's client runtime shape.

React navigation completion {#react-navigation-completion}

By default, await router.visit() and await router.refresh() wait for React to commit the updated page and URL. You can also request this explicitly with { resolveOn: 'commit' }.

When awaiting navigation inside startTransition, a <form action>, useActionState, or an async useForm() callback, pass { resolveOn: 'data' }:

startTransition(async () => {
  await saveUser();
  await router.refresh({ resolveOn: 'data' });
});

await router.visit('/account', { resolveOn: 'data' });

With 'data', the promise resolves when the destination's page data is ready, allowing the Action to finish while React renders the update. The transition can remain pending through Suspense. The DOM and URL may still show the previous page after await; use an effect or ref callback for work that requires the updated DOM.

@void/svelte {#void-svelte}

voidSvelte(options?) {#voidsvelte-options}

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

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

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

Signature:

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

Options:

interface VoidSvelteOptions {
  svelte?: SveltePluginOptions; // passed through to @sveltejs/vite-plugin-svelte
  viewTransitions?: boolean; // enable View Transitions API
  prefetch?: {
    defaultStrategy?: boolean | LinkPrefetchStrategy | LinkPrefetchStrategy[]; // default: false
    hoverDelay?: number; // default: 75 (ms)
    cacheFor?: number | string | [string, string]; // default: '30s'
  };
}

Svelte Runtime {#svelte-runtime}

Imported from "@void/svelte".

Export Description
Link Svelte component for SPA navigation. Renders <a> for GET, <button> for non-GET methods. Props: href, method, data, prefetch, cacheFor, preserveScroll, preserveState, replace, reloadDocument, viewTransition, activeMatch, onNavigate. Adds aria-current="page" and data-void-active to the link to the current page (active links), and data-void-pending to links to a page while it loads (pending links).
useForm(url, defaults, options?) Form helper using Svelte 5 runes. Returns { data, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, setError, 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, preserveScroll }, where method can be "PUT", "PATCH", or "DELETE". Returns an ActionResult.
isVoidActionError(error) Returns true when error is a VoidActionError at any status, such as a thrown 401, 403, or 500. Narrows error to VoidActionError. See handling thrown errors.
isCallSiteActionError(error) Returns true only for the expected VoidActionError statuses that action() returns, such as 409 or 422.
useShared() Returns shared data. Middleware sets it with c.set("shared", {...}); a loader or action can update it. See Shared data.
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. Pass the page's pattern as the type argument, such as useParams<'/users/:id'>(), to type them.
useNavigation() Returns pending navigation state: { state, location, method }, where state is "idle", "loading", or "submitting" and location is the pending destination.

Svelte Link GET data is merged into the rendered href query string. Primitive values are serialized with String(value), arrays become repeated keys, null and undefined are omitted, and nested objects throw. prefetch and reloadDocument are GET-only and throw for mutation links.

@void/solid {#void-solid}

voidSolid(options?) {#voidsolid-options}

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

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

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

Signature:

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

Options:

interface VoidSolidOptions {
  solid?: SolidPluginOptions; // passed through to vite-plugin-solid
  viewTransitions?: boolean; // enable View Transitions API
  prefetch?: {
    defaultStrategy?: boolean | LinkPrefetchStrategy | LinkPrefetchStrategy[]; // default: false
    hoverDelay?: number; // default: 75 (ms)
    cacheFor?: number | string | [string, string]; // default: '30s'
  };
}

Solid Runtime {#solid-runtime}

Imported from "@void/solid".

Export Description
Link Solid component for SPA navigation. Renders <a> for GET, <button> for non-GET methods. Props: href, method, data, prefetch, cacheFor, preserveScroll, preserveState, replace, reloadDocument, viewTransition, activeMatch, onNavigate. Adds aria-current="page" and data-void-active to the link to the current page (active links), and data-void-pending to links to a page while it loads (pending links).
useForm(url, defaults, options?) Form helper using Solid stores. Returns { data, setData, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, setError, 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, preserveScroll }, where method can be "PUT", "PATCH", or "DELETE". Returns an ActionResult.
isVoidActionError(error) Returns true when error is a VoidActionError at any status, such as a thrown 401, 403, or 500. Narrows error to VoidActionError. See handling thrown errors.
isCallSiteActionError(error) Returns true only for the expected VoidActionError statuses that action() returns, such as 409 or 422.
useShared() Returns shared data. Middleware sets it with c.set("shared", {...}); a loader or action can update it. See Shared data.
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. Pass the page's pattern as the type argument, such as useParams<'/users/:id'>(), to type them.
useNavigation() Returns pending navigation state: { state, location, method }, where state is "idle", "loading", or "submitting" and location is the pending destination.

Solid Link GET data is merged into the rendered href query string. Primitive values are serialized with String(value), arrays become repeated keys, null and undefined are omitted, and nested objects throw. prefetch and reloadDocument are GET-only and throw for mutation links.

Solid re-creates the page on GET navigation and whenever the route or its params change, so useForm() picks up the destination record's URL and defaults; layouts persist. Within the same record, back/forward, mutations, and router.refresh() keep the page and update its props in place, as do resolved deferred props, so read props inside JSX or memos instead of copying them in the component body. Set preserveState explicitly to override the default for navigation within the same record.

Markdown Package {#markdown-package}

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

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

export default defineConfig({
  plugins: [voidPlugin(), voidReact(), voidMarkdown()],
});
Import path Contents
@void/md/plugin voidMarkdown(options?), MarkdownOptions, MdPage
@void/md useFrontmatter(), MdPage
@void/md/pages Generated metadata for Markdown pages, used for navigation, sidebars, and search indexes
@void/md/theme.css Full Markdown theme styles
@void/md/theme-content.css Content-only Markdown styles for apps that provide their own shell/layout

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

See Markdown Pages for setup and framework-specific examples.

Form

Each Pages adapter exports Form. Pass the object returned by useForm() as form; method defaults to post. It renders validation and action errors, preserves controlled input, and respects known quota retry deadlines without submitting automatically. renderError customizes action-error presentation; Svelte uses a snippet. See Actions and Forms.