> ## Documentation Index
> Fetch the complete documentation index at: https://docs.embededitor.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Next.js

> Use Embed Editor in Next.js, from a server component or a client component.

Render the editor in Next.js, with the App Router or the Pages Router.

> [!TIP]
>
> Try every prop live in the [playground](https://embededitor.com/playground#c=eyJlZGl0aW9uIjoiRlVMTCIsImZyYW1ld29yayI6Ik5FWFRKUyJ9), open on Next.js, and copy the code it writes.

> [tab] Free
>
> Free is on public npm, with no key. It has the Adjust tools, and a small "embededitor.com" badge in the corner of the menu.
>
> ## Install
>
> ```bash npm theme={"dark"}
> npm install @embededitor/free
> ```
>
> ```bash yarn theme={"dark"}
> yarn add @embededitor/free
> ```
>
> ```bash pnpm theme={"dark"}
> pnpm add @embededitor/free
> ```
>
> ```bash bun theme={"dark"}
> bun add @embededitor/free
> ```
>
> ## Render
>
> The React entry starts with `'use client'`, so a server component can render `EmbedEditor` directly.
>
> ```tsx app/edit/page.tsx theme={"dark"}
> import { EmbedEditor } from '@embededitor/free/react';
>
> const Page = () => (
>   <div style={{ height: '100dvh' }}>
>     <EmbedEditor src='/photos/sunset.jpg' />
>   </div>
> );
>
> export default Page;
> ```
>
> The server sends only an empty host (`<div data-ee-host="">`). The editor mounts in the browser after hydration, with no hydration warning.
>
> ## Update Props
>
> A server component can pass only serializable props. Callbacks such as `onProcess` and `onClose` need a client component around the editor.
>
> ```tsx app/edit/photo-editor.tsx theme={"dark"}
> 'use client';
>
> import { EmbedEditor } from '@embededitor/free/react';
>
> const PhotoEditor = ({ src }: { src: string }) => (
>   <EmbedEditor
>     layout='page'
>     onProcess={({ dest }) => {
>       console.info('saved', dest.name);
>     }}
>     src={src}
>   />
> );
>
> export default PhotoEditor;
> ```
>
> From there, props apply live as in [React](https://docs.embededitor.com/frameworks/react.md#update-props).
>
> ## Safe Areas
>
> Export the viewport from the root layout, so the editor knows about the notch and the home indicator.
>
> ```ts app/layout.tsx theme={"dark"}
> import type { Viewport } from 'next';
>
> export const viewport: Viewport = { initialScale: 1, viewportFit: 'cover', width: 'device-width' };
> ```
>
> ## Clean Up
>
> `openEditor` and `mountEditor` touch the DOM. Call them from an event handler or an effect, never during a server render. Importing either entry on the server touches nothing of `window`, `document` or `navigator`.
>
> The Pages Router works the same way: the page renders the empty host on the server and the editor after hydration. Verified with Next.js 14.2 (webpack) and 16.3 (Turbopack).

> [tab] Lite
>
> Lite has the Adjust tools, without the badge. It installs from the private registry, with the key of your license.
>
> ## Set Up the Registry
>
> Your license key is on its card in your account at `account.embededitor.com`. [Buy a plan](https://embededitor.com/pricing) to get one.
>
> Point the `@embededitor` scope at the registry, and keep the key in an environment variable named `EMBED_EDITOR_KEY`, out of git.
>
> For npm, pnpm, bun and Yarn 1, add this to the `.npmrc` of your project:
>
> ```ini .npmrc theme={"dark"}
> @embededitor:registry=https://get.embededitor.com/
> //get.embededitor.com/:_authToken=${EMBED_EDITOR_KEY}
> ```
>
> Yarn 2 and newer ignore `.npmrc`. Add this to `.yarnrc.yml` instead:
>
> ```yaml .yarnrc.yml theme={"dark"}
> npmScopes:
>   embededitor:
>     npmRegistryServer: "https://get.embededitor.com"
>     npmAuthToken: "${EMBED_EDITOR_KEY}"
> ```
>
> Set the key where your install runs, your shell or your CI's secrets, never in git:
>
> ```bash Terminal theme={"dark"}
> export EMBED_EDITOR_KEY=<your-key>
> ```
>
> ## Install
>
> ```bash npm theme={"dark"}
> npm install @embededitor/lite
> ```
>
> ```bash yarn theme={"dark"}
> yarn add @embededitor/lite
> ```
>
> ```bash pnpm theme={"dark"}
> pnpm add @embededitor/lite
> ```
>
> ```bash bun theme={"dark"}
> bun add @embededitor/lite
> ```
>
> ## Render
>
> The React entry starts with `'use client'`, so a server component can render `EmbedEditor` directly.
>
> ```tsx app/edit/page.tsx theme={"dark"}
> import { EmbedEditor } from '@embededitor/lite/react';
>
> const Page = () => (
>   <div style={{ height: '100dvh' }}>
>     <EmbedEditor src='/photos/sunset.jpg' />
>   </div>
> );
>
> export default Page;
> ```
>
> The server sends only an empty host (`<div data-ee-host="">`). The editor mounts in the browser after hydration, with no hydration warning.
>
> ## Update Props
>
> A server component can pass only serializable props. Callbacks such as `onProcess` and `onClose` need a client component around the editor.
>
> ```tsx app/edit/photo-editor.tsx theme={"dark"}
> 'use client';
>
> import { EmbedEditor } from '@embededitor/lite/react';
>
> const PhotoEditor = ({ src }: { src: string }) => (
>   <EmbedEditor
>     layout='page'
>     onProcess={({ dest }) => {
>       console.info('saved', dest.name);
>     }}
>     src={src}
>   />
> );
>
> export default PhotoEditor;
> ```
>
> From there, props apply live as in [React](https://docs.embededitor.com/frameworks/react.md#update-props).
>
> ## Safe Areas
>
> Export the viewport from the root layout, so the editor knows about the notch and the home indicator.
>
> ```ts app/layout.tsx theme={"dark"}
> import type { Viewport } from 'next';
>
> export const viewport: Viewport = { initialScale: 1, viewportFit: 'cover', width: 'device-width' };
> ```
>
> ## Clean Up
>
> `openEditor` and `mountEditor` touch the DOM. Call them from an event handler or an effect, never during a server render. Importing either entry on the server touches nothing of `window`, `document` or `navigator`.
>
> The Pages Router works the same way: the page renders the empty host on the server and the editor after hydration. Verified with Next.js 14.2 (webpack) and 16.3 (Turbopack).

> [tab] Full
>
> Full has every tool, without the badge. It installs from the private registry, with the key of your license.
>
> ## Set Up the Registry
>
> Your license key is on its card in your account at `account.embededitor.com`. [Buy a plan](https://embededitor.com/pricing) to get one.
>
> Point the `@embededitor` scope at the registry, and keep the key in an environment variable named `EMBED_EDITOR_KEY`, out of git.
>
> For npm, pnpm, bun and Yarn 1, add this to the `.npmrc` of your project:
>
> ```ini .npmrc theme={"dark"}
> @embededitor:registry=https://get.embededitor.com/
> //get.embededitor.com/:_authToken=${EMBED_EDITOR_KEY}
> ```
>
> Yarn 2 and newer ignore `.npmrc`. Add this to `.yarnrc.yml` instead:
>
> ```yaml .yarnrc.yml theme={"dark"}
> npmScopes:
>   embededitor:
>     npmRegistryServer: "https://get.embededitor.com"
>     npmAuthToken: "${EMBED_EDITOR_KEY}"
> ```
>
> Set the key where your install runs, your shell or your CI's secrets, never in git:
>
> ```bash Terminal theme={"dark"}
> export EMBED_EDITOR_KEY=<your-key>
> ```
>
> ## Install
>
> ```bash npm theme={"dark"}
> npm install @embededitor/full
> ```
>
> ```bash yarn theme={"dark"}
> yarn add @embededitor/full
> ```
>
> ```bash pnpm theme={"dark"}
> pnpm add @embededitor/full
> ```
>
> ```bash bun theme={"dark"}
> bun add @embededitor/full
> ```
>
> ## Render
>
> The React entry starts with `'use client'`, so a server component can render `EmbedEditor` directly.
>
> ```tsx app/edit/page.tsx theme={"dark"}
> import { EmbedEditor } from '@embededitor/full/react';
>
> const Page = () => (
>   <div style={{ height: '100dvh' }}>
>     <EmbedEditor src='/photos/sunset.jpg' />
>   </div>
> );
>
> export default Page;
> ```
>
> The server sends only an empty host (`<div data-ee-host="">`). The editor mounts in the browser after hydration, with no hydration warning.
>
> ## Update Props
>
> A server component can pass only serializable props. Callbacks such as `onProcess` and `onClose` need a client component around the editor.
>
> ```tsx app/edit/photo-editor.tsx theme={"dark"}
> 'use client';
>
> import { EmbedEditor } from '@embededitor/full/react';
>
> const PhotoEditor = ({ src }: { src: string }) => (
>   <EmbedEditor
>     layout='page'
>     onProcess={({ dest }) => {
>       console.info('saved', dest.name);
>     }}
>     src={src}
>   />
> );
>
> export default PhotoEditor;
> ```
>
> From there, props apply live as in [React](https://docs.embededitor.com/frameworks/react.md#update-props).
>
> ## Safe Areas
>
> Export the viewport from the root layout, so the editor knows about the notch and the home indicator.
>
> ```ts app/layout.tsx theme={"dark"}
> import type { Viewport } from 'next';
>
> export const viewport: Viewport = { initialScale: 1, viewportFit: 'cover', width: 'device-width' };
> ```
>
> ## Clean Up
>
> `openEditor` and `mountEditor` touch the DOM. Call them from an event handler or an effect, never during a server render. Importing either entry on the server touches nothing of `window`, `document` or `navigator`.
>
> The Pages Router works the same way: the page renders the empty host on the server and the editor after hydration. Verified with Next.js 14.2 (webpack) and 16.3 (Turbopack).

## Next Steps

> [card] [React](https://docs.embededitor.com/frameworks/react.md)
>
> The component, the modal and live props.

> [card] [Inline and Page](https://docs.embededitor.com/guides/inline.md)
>
> Show the editor in a box or over the whole viewport.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.