Next.js

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

Take into this GitHub repository for a demo: https://github.com/polotno-project/polotno-next

1. Install dependencies:

npm install polotno canvas
  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

Add the following into package.json and reinstall dependencies.

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

For pnpm

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

Config (outdated)

Note: these configs were required in previous versions of nextjs. We will keep them in docs temporary.

If you use app folder make sure to put this into next.config.js

/** @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;

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

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