# Integration

## Module bundler

If you are using a module bundler (for instance, Webpack), you can import it as an ES6 module as shown below

```js
import { Excalidraw } from "@excalidraw/excalidraw";
```

:::info

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.

:::

```jsx live
function App() {
  return (
    <>
      <h1 style={{ textAlign: "center" }}>Excalidraw Example</h1>
      <div style={{ height: "500px" }}>
        <Excalidraw />
      </div>
    </>
  );
}
```

### 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 :point_down:

```jsx showLineNumbers
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 :point_down:

<Tabs>
  <TabItem value="Excalidraw Wrapper" label="Excalidraw Wrapper" >

  ```jsx showLineNumbers
  "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;
  ```

  </TabItem>

  <TabItem value="pages" label="Pages router">

  ```jsx showLineNumbers
  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 />
    );
  }
  ```
  </TabItem>

  <TabItem value="app" label="App router">

  ```jsx showLineNumbers
  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 />
    );
  }
  ```

  </TabItem>
</Tabs>

{/* Link  should be updated to point to the latest! */}
Here is a [source code](https://github.com/excalidraw/excalidraw/tree/master/examples/with-nextjs) for the example with app and pages router. You you can try it out [here](https://excalidraw-package-example-with-nextjs.vercel.app/).

The `types` are available at `@excalidraw/excalidraw/types`, check [CodeSandbox](https://codesandbox.io/p/sandbox/github/excalidraw/excalidraw/tree/master/examples/with-script-in-browser) example for details.

### 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.

:::info

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 :point_down:

```
 define: {
    "process.env.IS_PREACT": JSON.stringify("true"),
  },
```
:::

## Browser

To use it Excalidraw in a browser directly, use the following setup :point_down:

> **Note**: We rely on import maps to de-duplicate `react`, `react-dom` and `react/jsx-runtime` versions.

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

<Tabs>
  <TabItem value="html" label="html">

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Excalidraw in browser</title>
    <meta charset="UTF-8" />
    <link
      rel="stylesheet"
      href="https://esm.sh/@excalidraw/excalidraw@0.18.0/dist/dev/index.css"
    />
    <link rel="stylesheet" href="./index.css" />
    <script>
    	window.EXCALIDRAW_ASSET_PATH = "https://esm.sh/@excalidraw/excalidraw@0.18.0/dist/prod/";
		</script>
    <script type="importmap">
      {
        "imports": {
          "react": "https://esm.sh/react@19.0.0",
          "react/jsx-runtime": "https://esm.sh/react@19.0.0/jsx-runtime",
          "react-dom": "https://esm.sh/react-dom@19.0.0"
          }
      }
    </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>
```

</TabItem>
<TabItem value="js" label="Javascript">

```js showLineNumbers
// See https://www.npmjs.com/package/@excalidraw/excalidraw documentation.
import * as ExcalidrawLib from 'https://esm.sh/@excalidraw/excalidraw@0.18.0/dist/dev/index.js?external=react,react-dom';
import React from "https://esm.sh/react@19.0.0";
import ReactDOM from "https://esm.sh/react-dom@19.0.0"

window.ExcalidrawLib = ExcalidrawLib;
console.log("Excalidraw library", ExcalidrawLib);

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));
```

</TabItem>
</Tabs>

You can try it out [here](https://jsfiddle.net/vfn6dm14/3/).
