Shared Props Typing¶
TypeScript types for shared data across pages.
Overview¶
Litestar-Vite generates types for shared props:
GeneratedSharedProps: Built-in props (flash, errors, csrf_token)User: Default user interface (extensible)AuthData: Default auth interface (extensible)SharedProps: User-extensible interface forshare()dataFullSharedProps: CombinedGeneratedSharedProps & SharedProps
Generated Types¶
Default generated page-props.ts:
// Built-in props (always present)
export interface GeneratedSharedProps {
flash: FlashMessages;
errors: Record<string, string>;
csrf_token: string;
}
// Default user interface - extend via module augmentation
export interface User {
id: string;
email: string;
name?: string | null;
}
// Default auth interface
export interface AuthData {
isAuthenticated: boolean;
user?: User | null;
}
// Flash messages
export interface FlashMessages {
[category: string]: string[];
}
// User-extensible interface
export interface SharedProps {}
// Combined type
export type FullSharedProps = GeneratedSharedProps & SharedProps;
Extending Interfaces¶
Use TypeScript module augmentation to extend types:
src/types/shared-props.ts¶
// Extend the User interface
declare module "litestar-vite-plugin/inertia" {
interface User {
avatarUrl?: string | null;
roles: string[];
createdAt: string;
}
}
// Extend SharedProps for share() data
declare module "litestar-vite-plugin/inertia" {
interface SharedProps {
auth: AuthData;
locale: string;
notifications: Notification[];
}
}
Then import in your app:
src/main.ts¶
import "./types/shared-props"; // Load augmentations
// Now User and SharedProps are extended everywhere
Using in Components¶
import { usePage } from "@inertiajs/react";
import type { FullSharedProps, PageProps } from "@/generated/page-props";
type Props = PageProps["Dashboard"] & FullSharedProps;
export default function Dashboard() {
const { props } = usePage<{ props: Props }>();
// Type-safe access to shared props
const { auth, flash, locale } = props;
return (
<div>
{auth.isAuthenticated && (
<span>Hello, {auth.user?.name}</span>
)}
{flash.success?.map((msg) => (
<Alert type="success">{msg}</Alert>
))}
</div>
);
}
Disabling Defaults¶
If your user model doesn’t match the defaults:
from litestar_vite.config import InertiaTypeGenConfig
InertiaConfig(
type_gen=InertiaTypeGenConfig(
include_default_auth=False, # No default User/AuthData
include_default_flash=True, # Keep FlashMessages
),
)
Then define your own types:
// Define custom User from scratch
declare module "litestar-vite-plugin/inertia" {
interface User {
uuid: string; // No id!
username: string; // No email!
permissions: string[];
}
interface AuthData {
loggedIn: boolean; // Different naming
currentUser?: User;
}
}
Common Patterns¶
Guard-based sharing:
# In guard
share(connection, "auth", {
"isAuthenticated": bool(connection.user),
"user": serialize_user(connection.user),
})
Middleware sharing:
# In middleware
share(request, "locale", request.headers.get("Accept-Language", "en"))
share(request, "notifications", get_unread_notifications(request.user))
Type definition:
interface SharedProps {
auth: AuthData;
locale: string;
notifications: Array<{
id: number;
message: string;
read: boolean;
}>;
}
See Also¶
Shared Data - Using share()
Typed Page Props - PageProps usage
Configuration - InertiaTypeGenConfig