UNPKG

@adonisjs/inertia

Version:

Official Inertia.js adapter for AdonisJS

262 lines (261 loc) 8.32 kB
import { type Vite } from '@adonisjs/vite'; import type { HttpContext } from '@adonisjs/core/http'; import { type ServerRenderer } from './server_renderer.js'; import type { PageProps, PageObject, AsPageProps, RequestInfo, InertiaConfig, ComponentProps, SharedProps } from './types.js'; import { defer, merge, always, optional, deepMerge } from './props.ts'; import { type AsyncOrSync } from '@poppinss/utils/types'; /** * Main class used to interact with Inertia * * Provides a complete interface for handling Inertia.js requests, rendering pages, * managing props, and controlling page navigation behavior. * * @example * ```js * const inertia = new Inertia(ctx, config, vite, serverRenderer) * * // Render a page * const result = await inertia.render('Home', { user: { name: 'John' } }) * * // Clear browser history * inertia.clearHistory() * * // Redirect to a different location * inertia.location('/dashboard') * ``` */ export declare class Inertia<Pages> { #private; protected ctx: HttpContext; protected config: InertiaConfig; /** * Defer prop evaluation until client-side rendering * * @example * ```js * { * expensiveData: inertia.defer(() => computeExpensiveData()) * } * ``` */ defer: typeof defer; /** * Always include prop in both server and client renders * * @example * ```js * { * currentUser: inertia.always(() => getCurrentUser()) * } * ``` */ always: typeof always; /** * Merge prop with existing client-side data * * @example * ```js * { * posts: inertia.merge(() => getPosts()) * } * ``` */ merge: typeof merge; /** * Include prop only when specifically requested * * @example * ```js * { * optionalData: inertia.optional(() => getOptionalData()) * } * ``` */ optional: typeof optional; /** * Deep merge prop with existing client-side data * * @example * ```js * { * settings: inertia.deepMerge(() => getSettings()) * } * ``` */ deepMerge: typeof deepMerge; /** * Creates a new Inertia instance * * @param ctx - HTTP context for the current request * @param config - Inertia configuration object * @param vite - Vite instance for asset management * @param serverRenderer - Optional server renderer for SSR * * @example * ```js * const inertia = new Inertia(ctx, { * rootView: 'app', * ssr: { enabled: true } * }, vite, serverRenderer) * ``` */ constructor(ctx: HttpContext, config: InertiaConfig, vite?: Vite, serverRenderer?: ServerRenderer); /** * Extract Inertia-specific information from request headers * * Parses various Inertia headers to determine request type and props filtering. * * @param reCompute - Whether to recompute the request info instead of using cached version * @returns The request information object containing Inertia-specific data * * @example * ```js * const info = inertia.requestInfo() * if (info.isInertiaRequest) { * // Handle as Inertia request * } * ``` */ requestInfo(reCompute?: boolean): RequestInfo; /** * Compute and cache the assets version * * Uses Vite manifest hash when available, otherwise defaults to '1'. * * @returns The computed version string for asset versioning */ getVersion(): string; /** * Determine if server-side rendering is enabled for a specific component * * Checks global SSR settings and component-specific configuration. * * @param component - The component name to check * @returns Promise resolving to true if SSR is enabled for the component * * @example * ```js * const shouldSSR = await inertia.ssrEnabled('UserProfile') * if (shouldSSR) { * // Render on server * } * ``` */ ssrEnabled<Page extends keyof Pages & string>(component: Page): Promise<boolean>; /** * Share props across all pages * * Merges the provided props with existing shared state, making them available * to all pages rendered by this Inertia instance. Shared props are included * in every page render alongside page-specific props. * * @param sharedState - Props to share across all pages * @returns The Inertia instance for method chaining * * @example * ```js * // Share user data across all pages * inertia.share({ * user: getCurrentUser(), * flash: getFlashMessages() * }) * * // Chain multiple shares * inertia * .share({ currentUser: user }) * .share({ permissions: userPermissions }) * ``` */ share(sharedState: PageProps | (() => AsyncOrSync<PageProps>)): this; /** * Build a page object with processed props and metadata * * Creates the complete page object that will be sent to the client or used for SSR. * * @param page - The page component name * @param pageProps - Props to pass to the page component * @returns Promise resolving to the complete page object * * @example * ```js * const pageObject = await inertia.page('Dashboard', { * user: { name: 'John' }, * posts: defer(() => getPosts()) * }) * ``` */ page<Page extends keyof Pages & string>(page: Page, pageProps: Pages[Page] extends ComponentProps ? AsPageProps<Omit<Pages[Page], keyof SharedProps>> : never): Promise<PageObject<Pages[Page]>>; /** * Render a page using Inertia * * This method handles three distinct rendering scenarios: * 1. Inertia requests - Returns JSON page object for client-side navigation * 2. Initial page loads with SSR - Returns HTML with server-rendered content * 3. Initial page loads without SSR - Returns HTML for client-side hydration * * @param page - The page component name to render * @param pageProps - Props to pass to the page component * @param viewProps - Additional props to pass to the root view template * @returns Promise resolving to PageObject for Inertia requests, HTML string for initial page loads * * @example * ```js * // For Inertia requests, returns PageObject * const result = await inertia.render('Profile', { * user: getCurrentUser(), * posts: defer(() => getUserPosts()) * }) * * // For initial page loads, returns HTML string * const html = await inertia.render('Home', { welcome: 'Hello World' }) * ``` */ render<Page extends keyof Pages & string>(page: Page, pageProps: Pages[Page] extends ComponentProps ? AsPageProps<Omit<Pages[Page], keyof SharedProps>> : never, viewProps?: Record<string, any>): Promise<string | PageObject<Pages[Page]>>; /** * Clear the browser history on the next navigation * * Instructs the client to clear the browser history stack when navigating. * * @example * ```js * inertia.clearHistory() * return inertia.render('Dashboard', props) * ``` */ clearHistory(): void; /** * Control whether browser history should be encrypted * * Enables or disables encryption of sensitive data in browser history. * * @param encrypt - Whether to encrypt history (defaults to true) * * @example * ```js * // Enable encryption for sensitive pages * inertia.encryptHistory(true) * * // Disable encryption for public pages * inertia.encryptHistory(false) * ``` */ encryptHistory(encrypt?: boolean): void; /** * Redirect to a different location * * Sets the appropriate headers to redirect the client to a new URL. * Uses a 409 status code which Inertia.js interprets as a redirect instruction. * * @param url - The URL to redirect to * * @example * ```js * // Redirect after login * inertia.location('/dashboard') * * // Redirect with full URL * inertia.location('https://example.com/external') * ``` */ location(url: string): void; }