summaryrefslogtreecommitdiffstats
path: root/dev-docs/docs/@excalidraw/excalidraw/integration.mdx
diff options
context:
space:
mode:
Diffstat (limited to 'dev-docs/docs/@excalidraw/excalidraw/integration.mdx')
-rw-r--r--dev-docs/docs/@excalidraw/excalidraw/integration.mdx238
1 files changed, 238 insertions, 0 deletions
diff --git a/dev-docs/docs/@excalidraw/excalidraw/integration.mdx b/dev-docs/docs/@excalidraw/excalidraw/integration.mdx
new file mode 100644
index 0000000..117877b
--- /dev/null
+++ b/dev-docs/docs/@excalidraw/excalidraw/integration.mdx
@@ -0,0 +1,238 @@
+# 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/).