File-Based Routing with GraphQL
Define routes with page.tsx files. Declare GraphQL queries as types and Pastoria preloads them on the server during SSR. No loading spinners on initial page load.
import { graphql, usePreloadedQuery } from 'react-relay';
export type Queries = {
user: page_UserQuery;
};
export default function UserPage({
queries,
}: PastoriaPageProps<'/users/[id]'>) {
const { user } = usePreloadedQuery(graphql`
query page_UserQuery($id: String!) @preloadable {
user(id: $id) {
name
...UserCard_user
}
}
`, queries.user);
return <UserCard user={user} />;
}
Type-Safe Navigation
The generated router provides type-safe navigation hooks and link components. Route IDs, params, and query variables are all checked at compile time.
import { useFragment, graphql } from 'react-relay';
import { RouteLink } from '#genfiles/router/router';
function UserCard(props: { user: UserCard_user$key }) {
const user = useFragment(
graphql`fragment UserCard_user on User {
id
name
}`,
props.user
);
return (
<RouteLink route="/users/[id]" params={{ id: user.id }}>
{user.name}
</RouteLink>
);
}
Unified Code Generation
Server-side rendering, code splitting, and lazy loading out of the box. Run pastoria generate to wire up your routes, then pastoria dev to start developing with hot module replacement powered by Vite.
# Run the full generate pipeline
$ pnpm generate
# Start dev server backed by Vite
$ pastoria dev
# Build for production
$ pastoria build
# Deploy with the standalone server
$ pastoria-server