Integration
Module bundler
If you are using a module bundler (for instance, Webpack), you can import it as an ES6 module as shown below
import { Excalidraw } from "@excalidraw/excalidraw";
Throughout the documentation we use live, editable Excalidraw examples like the one shown below.
While we aim for the examples to closely reflect what you'd get if you rendered it yourself, we actually initialize it with some props behind the scenes.
For example, we're passing a theme
prop to it based on the current color theme of the docs you're just reading.
Next.js
Since Excalidraw doesn't support server side rendering
so it should be rendered only on client
. The way to achieve this in next.js is using next.js dynamic import
.
If you want to only import Excalidraw
component you can do 👇
import dynamic from "next/dynamic";
const Excalidraw = dynamic(
async () => (await import("@excalidraw/excalidraw")).Excalidraw,
{
ssr: false,
},
);
export default function App() {
return <Excalidraw />;
}
However the above component only works for named component exports. If you want to import some util / constant or something else apart from Excalidraw, then this approach will not work. Instead you can write a wrapper over Excalidraw and import the wrapper dynamically.
If you are using pages router
then importing the wrapper dynamically would work, where as if you are using app router
then you will have to also add useClient
directive on top of the file in addition to dynamically importing the wrapper as shown 👇
- Excalidraw Wrapper
- Pages router
- App router
"use client";
import { Excalidraw, convertToExcalidrawElements } from "@excalidraw/excalidraw";
import "@excalidraw/excalidraw/index.css";
const ExcalidrawWrapper: React.FC = () => {
console.info(convertToExcalidrawElements([{
type: "rectangle",
id: "rect-1",
width: 186.47265625,
height: 141.9765625,
},]));
return (
<div style={{height:"500px", width:"500px"}}>
<Excalidraw />
</div>
);
};
export default ExcalidrawWrapper;
import dynamic from "next/dynamic";
// Since client components get prerenderd on server as well hence importing
// the excalidraw stuff dynamically with ssr false
const ExcalidrawWrapper = dynamic(
async () => (await import("../excalidrawWrapper")).default,
{
ssr: false,
},
);
export default function Page() {
return (
<ExcalidrawWrapper />
);
}
import dynamic from "next/dynamic";
// Since client components get prerenderd on server as well hence importing
// the excalidraw stuff dynamically with ssr false
const ExcalidrawWrapper = dynamic(
async () => (await import("../excalidrawWrapper")).default,
{
ssr: false,
},
);
export default function Page() {
return (
<ExcalidrawWrapper />
);
}
Here is a source code for the example with app and pages router. You you can try it out here.
The types
are available at @excalidraw/excalidraw/types
, you can view example for typescript
Preact
Since we support umd
build ships with react/jsx-runtime
and react-dom/client
inlined with the package. This conflicts with Preact
and hence the build doesn't work directly with Preact
.
However we have shipped a separate build for Preact
so if you are using Preact
you need to set process.env.IS_PREACT
to true
to use the Preact
build.
Once the above env
variable is set, you will be able to use the package in Preact
as well.
When using vite
or any build tools, you will have to make sure the process
is accessible as we are accessing process.env.IS_PREACT
to decide whether to use preact
build.
Since Vite removes env variables by default, you can update the vite config to ensure its available 👇
define: {
"process.env.IS_PREACT": JSON.stringify("true"),
},
Browser
To use it in a browser directly:
For development use 👇
<script
type="text/javascript"
src="https://unpkg.com/@excalidraw/excalidraw/dist/excalidraw.development.js"
></script>
For production use 👇
<script
type="text/javascript"
src="https://unpkg.com/@excalidraw/excalidraw/dist/excalidraw.production.min.js"
></script>
You will need to make sure react
, react-dom
is available as shown in the below example. For prod please use the production versions of react
, react-dom
.
- html
- Javascript
<!DOCTYPE html>
<html>
<head>
<title>Excalidraw in browser</title>
<meta charset="UTF-8" />
<script src="https://unpkg.com/react@18.2.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.2.0/umd/react-dom.development.js"></script>
<script
type="text/javascript"
src="https://unpkg.com/@excalidraw/excalidraw/dist/excalidraw.development.js"
></script>
</head>
<body>
<div class="container">
<h1>Excalidraw Embed Example</h1>
<div id="app"></div>
</div>
<script type="text/javascript" src="packages/excalidraw/index.js"></script>
</body>
</html>
const App = () => {
return React.createElement(
React.Fragment,
null,
React.createElement(
"div",
{
style: { height: "500px" },
},
React.createElement(ExcalidrawLib.Excalidraw),
),
);
};
const excalidrawWrapper = document.getElementById("app");
const root = ReactDOM.createRoot(excalidrawWrapper);
root.render(React.createElement(App));