Using RVE in an existing Next.js App
Step-by-step guide to integrate React Video Editor (RVE) into your existing Next.js (App Router) project.
Overview
This guide shows how to add React Video Editor (RVE) to an existing Next.js App Router project. You'll:
- Create or confirm Tailwind setup
- Ensure TypeScript path aliases
- Add RVE dependencies and migrate source code
- Configure an SSR renderer using a Next.js Route Handler
Prerequisites: Node.js 18+, npm or pnpm, Next.js 13.4+ (App Router), basic familiarity with Next.js.
Nudge for a Video Tutorial
Tired of reading long wordy docs? Same. Email hello@reactvideoeditor.com and tell Sam (our founder) to finally make some video tutorial.
Quick checklist
- Tailwind configured and imported in
app/globals.css
-
@
alias points to./src
(or project root if you prefer) - RVE deps installed and
ReactVideoEditor
page wired - SSR route handler added and referenced by
HttpRenderer
1) Ensure Tailwind CSS
If your project doesn't already use Tailwind, install and enable it:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
In tailwind.config.ts
(or tailwind.config.js
), include your app
, components
, and any library paths:
import type { Config } from "tailwindcss";
export default {
content: [
"./app/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./src/**/*.{ts,tsx}",
],
theme: { extend: {} },
plugins: [],
} satisfies Config;
In app/globals.css
, import Tailwind:
@tailwind base;
@tailwind components;
@tailwind utilities;
2) Configure TypeScript base URL and alias
In your root tsconfig.json
(or tsconfig.base.json
), add an @
alias to src
(recommended) or project root:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
If you store code outside src
, adjust the path accordingly.
3) Install shadcn/ui (optional)
RVE works with any UI system. If you want to use shadcn/ui components, initialize it:
npx shadcn@latest init
Pick any theme you like.
4) Add dependencies
Merge the following into your package.json
dependencies, then install:
{
"dependencies": {
"@radix-ui/react-alert-dialog": "^1.1.2",
"@radix-ui/react-avatar": "^1.1.1",
"@radix-ui/react-collapsible": "^1.1.1",
"@radix-ui/react-context-menu": "^2.2.1",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-dropdown-menu": "^2.1.2",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-popover": "^1.1.2",
"@radix-ui/react-scroll-area": "^1.1.0",
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slider": "^1.2.0",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.1.1",
"@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-toast": "^1.2.1",
"@radix-ui/react-toggle": "^1.1.0",
"@radix-ui/react-toggle-group": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.3",
"@remotion/bundler": "4.0.272",
"@remotion/cli": "4.0.272",
"@remotion/google-fonts": "4.0.272",
"@remotion/lambda": "4.0.272",
"@remotion/player": "4.0.272",
"@remotion/renderer": "4.0.272",
"date-fns": "^4.1.0",
"mediabunny": "^1.11.2",
"posthog-js": "^1.268.6",
"react-best-gradient-color-picker": "^3.0.14",
"react-hotkeys-hook": "^4.6.1",
"remotion": "4.0.272",
"tailwindcss-animate": "^1.0.7",
"uuid": "^10.0.0",
"zustand": "^4.4.6"
}
}
Then install:
npm i
5) Copy RVE source
- From your RVE Pro project, copy the
reactvideoeditor
directory into your Next.js app atsrc/reactvideoeditor
. - Copy
contestants.ts
into your app'ssrc
directory.
6) Create a client page and wire the editor
Create a new page, e.g. app/editor/page.tsx
:
"use client";
import React from "react";
import { HttpRenderer } from "@/reactvideoeditor/pro/utils/http-renderer";
import { ReactVideoEditor } from "@/reactvideoeditor/pro/components/react-video-editor";
import { createPexelsVideoAdaptor } from "@/reactvideoeditor/pro/adaptors/pexels-video-adaptor";
import { createPexelsImageAdaptor } from "@/reactvideoeditor/pro/adaptors/pexels-image-adaptor";
import { DEFAULT_OVERLAYS } from "@/constants";
import "@/reactvideoeditor/pro/styles.css";
export default function EditorPage() {
const PROJECT_ID = "TestComponent"; // Must match your Remotion composition ID
const ssrRenderer = React.useMemo(
() =>
new HttpRenderer("/api/latest/ssr", {
type: "ssr",
entryPoint: "/api/latest/ssr",
}),
[]
);
return (
<div className="w-full h-[100dvh]">
<ReactVideoEditor
projectId={PROJECT_ID}
defaultOverlays={DEFAULT_OVERLAYS as any}
fps={30}
renderer={ssrRenderer}
disabledPanels={[]}
defaultTheme="dark"
adaptors={{
video: [createPexelsVideoAdaptor("keys")],
images: [createPexelsImageAdaptor("keys")],
}}
showDefaultThemes
sidebarWidth="clamp(350px, 25vw, 500px)"
sidebarIconWidth="57.6px"
showIconTitles={false}
/>
</div>
);
}
Notes:
- This page must be a Client Component (
"use client"
) because the editor relies on browser APIs. - Import the provided
styles.css
from RVE.
7) Add the SSR route handler
Create app/api/latest/ssr/route.ts
:
import { NextResponse } from "next/server";
export async function POST() {
// TODO: Wire to your SSR rendering logic. For example, forward to Remotion renderer.
return NextResponse.json({ ok: true });
}
Point HttpRenderer
at this endpoint (/api/latest/ssr
). Replace with real rendering logic when ready.
8) Add your logo (optional)
If you want a sidebar logo, add public/logo.png
(or use next/image
) and pass it via a prop if your wrapper supports it.
9) Run the app
npm run dev
Open http://localhost:3000/editor
.
Notes and troubleshooting
-
App Router vs Pages Router: These steps target the App Router. If you use the Pages Router, create
pages/api/latest/ssr.ts
for the API, and put the editor underpages/editor.tsx
withexport default
. -
Path alias issues: If imports using
@/
fail, confirm yourtsconfig.json
baseUrl
andpaths
configuration. -
Styles not applying: Ensure
app/globals.css
includes Tailwind and thatstyles.css
from RVE is imported in your client page.