Next.js

How to use Polotno Design editor with Next.js framework?

Next.js version 14

1. Install dependencies:

npm install polotno canvas@next
  1. Create a file components/editor.js . Do not place it inside pages or app folders to avoid server-side rendering.

import React from 'react';
import { PolotnoContainer, SidePanelWrap, WorkspaceWrap } from 'polotno';
import { Toolbar } from 'polotno/toolbar/toolbar';
import { PagesTimeline } from 'polotno/pages-timeline';
import { ZoomButtons } from 'polotno/toolbar/zoom-buttons';
import { SidePanel } from 'polotno/side-panel';
import { Workspace } from 'polotno/canvas/workspace';

import { createStore } from 'polotno/model/store';

const store = createStore({
  key: 'YOUR_API_KEY', // you can create it here: https://polotno.com/cabinet/
  // you can hide back-link on a paid license
  // but it will be good if you can keep it for Polotno project support
  showCredit: true,
});
const page = store.addPage();

export const Editor = () => {
  return (
    <PolotnoContainer style={{ width: '100vw', height: '100vh' }}>
      <link
        rel="stylesheet"
        href="https://unpkg.com/@blueprintjs/core@latest/lib/css/blueprint.css"
      />
      <SidePanelWrap>
        <SidePanel store={store} />
      </SidePanelWrap>
      <WorkspaceWrap>
        <Toolbar store={store} downloadButtonEnabled />
        <Workspace store={store} />
        <ZoomButtons store={store} />
        <PagesTimeline store={store} />
      </WorkspaceWrap>
    </PolotnoContainer>
  );
};

export default Editor;

  1. Import editor in a client component with dynamic loading:

'use client';

import dynamic from 'next/dynamic';
const Editor = dynamic(() => import('../components/editor'), {
  ssr: false,
});

export default function Home() {
  return <Editor />;
}

Next.js version 15

At the current moment next.js version 15 is not supported. We are waiting for updates from some internal dependencies to support it.

Add the following into package.json

  "overrides": {
    "polotno": {
      "react": "^19",
      "react-dom": "^19",
      "react-konva": "^19"
    }
  },

Next.js version 13

  1. Create an isolated React component for all Polotno-related UI.

  2. Put that component inside components folder. Or it can be another folder.
    ⚠️ Important: avoid using pages or app folders.

  3. Use dynamic import for that component. It will help to avoid SSR errors. https://nextjs.org/docs/advanced-features/dynamic-import

  4. In some versions of next.js you may need to set up next.config.js to make it work:

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.externals = [...config.externals, { canvas: 'canvas' }]; // required to make Konva & react-konva work
    return config;
  },
};

module.exports = nextConfig;

If you use turbopack you may need to create an empty file called empty.js and use this config to disable canvas module loading:

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    turbo: {
      resolveAlias: {
        canvas: { browser: './empty.js' },
      },
    },
  },
};

export default nextConfig;


Note: polotno is not designed for Server-Side Rendering. Most of its modules are browser-only. This is why we need to move the editor component out of pages or app folder. Otherwise, Next.js will try to render it on the server and it will fail.

import dynamic from 'next/dynamic';
const Editor = dynamic(() => import('../components/editor'), {
  ssr: false,
});

export default function IndexPage() {
  return (
    <div>
      <Editor />
    </div>
  );
}

News, updates and promos – be the first to get 'em

News, updates and promos – be the first to get 'em