---
title: Next.js integration
description: Use one repository for web routes and videos without coupling the two entry systems.
---

Install Odori in an existing Next.js application:

```bash
pnpm add odori @odori/next
pnpm add -D @odori/cli
pnpm odori init
```

<FileTree>

- app/
  - page.tsx
  - videos/
    - [id]/
      - page.tsx
  - api/
    - exports/
      - route.ts
- videos/
  - layout.tsx
  - components/
    - title-reveal/
      - title-reveal.tsx
      - title-reveal.preview.tsx
  - launch/
    - video.tsx
- components/
  - product-ui/
- odori.config.ts
- next.config.ts

</FileTree>

```ts title="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

```tsx title="app/videos/[id]/page.tsx"
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

```ts title="app/api/exports/route.ts"
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.

:::note
`@odori/next/server` loads the project graph in Node. Import it only from
server components, route handlers, or server actions.
:::
