Next.js integration
Use one repository for web routes and videos without coupling the two entry systems.
Install Odori in an existing Next.js application:
pnpm add odori @odori/next
pnpm add -D @odori/cli
pnpm odori init
- app/
- page.tsx
- videos/
- [id]/
- page.tsx
- [id]/
- api/
- exports/
- route.ts
- exports/
- videos/
- layout.tsx
- components/
- title-reveal/
- title-reveal.tsx
- title-reveal.preview.tsx
- title-reveal/
- launch/
- video.tsx
- components/
- product-ui/
- odori.config.ts
- next.config.ts
import {withOdori} from "@odori/next";
import type {NextConfig} from "next";
const nextConfig: NextConfig = {};
export default withOdori(nextConfig);
The integration generates static imports for videos/ and exposes the catalog
to server and client code without importing Node-only render machinery into the
browser bundle.
Embed a live preview
import {OdoriPlayer} from "@odori/next/player";
import {getVideo} from "@odori/next/server";
export default async function VideoPage({params}) {
const {id} = await params;
const {entry} = await getVideo(id);
return <OdoriPlayer entry={entry} controls autoPlay />;
}
@odori/next/player is a client component. Page chrome, metadata, and the
reserved player aspect ratio can remain in the server-rendered shell.
Queue an export
import {createExport} from "@odori/next/server";
export async function POST(request: Request) {
const input = await request.json();
const job = await createExport(input);
return Response.json(job, {status: 202});
}
createExport() freezes the manifest and records a queued job. Read job state
with getExport(id) and list history with listExports(). Render workers stay
deployment-independent: the application submits jobs and reads status, and does
not need Chromium in every application function.