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
ReactVideoEditorpage 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 -pIn 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 initPick 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.356",
"@remotion/cli": "4.0.356",
"@remotion/google-fonts": "4.0.356",
"@remotion/lambda": "4.0.356",
"@remotion/player": "4.0.356",
"@remotion/renderer": "4.0.356",
"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.356",
"tailwindcss-animate": "^1.0.7",
"uuid": "^10.0.0",
"zustand": "^4.4.6"
}
}Then install:
npm i5) Copy RVE source
- From your RVE Pro project, copy the
reactvideoeditordirectory into your Next.js app atsrc/reactvideoeditor. - Copy
contestants.tsinto your app'ssrcdirectory.
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.cssfrom 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 devOpen 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.tsfor the API, and put the editor underpages/editor.tsxwithexport default. -
Path alias issues: If imports using
@/fail, confirm yourtsconfig.jsonbaseUrlandpathsconfiguration. -
Styles not applying: Ensure
app/globals.cssincludes Tailwind and thatstyles.cssfrom RVE is imported in your client page.