From 2789d08154a384ae98d9e9d9f70a01334d45ade9 Mon Sep 17 00:00:00 2001 From: Aakansha Doshi Date: Thu, 25 Jan 2024 20:26:48 +0530 Subject: [PATCH] docs: update the docs for next js integration (#7605) * docs: update the docs for next js integration * update * update * update docs with tabbed examples * fix --- .../@excalidraw/excalidraw/integration.mdx | 101 ++++++++++++++---- 1 file changed, 79 insertions(+), 22 deletions(-) diff --git a/dev-docs/docs/@excalidraw/excalidraw/integration.mdx b/dev-docs/docs/@excalidraw/excalidraw/integration.mdx index 87eb3777db..d6bf3fd0d1 100644 --- a/dev-docs/docs/@excalidraw/excalidraw/integration.mdx +++ b/dev-docs/docs/@excalidraw/excalidraw/integration.mdx @@ -32,15 +32,9 @@ function App() { ### Next.js -Since _Excalidraw_ doesn't support server side rendering, you should render the component once the host is `mounted`. +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`. -Here are two ways on how you can render **Excalidraw** on **Next.js**. - - - -1. Using **Next.js Dynamic** import [Recommended]. - -Since Excalidraw doesn't support server side rendering so you can also use `dynamic import` to render by setting `ssr` to `false`. +If you want to only import `Excalidraw` component you can do :point_down: ```jsx showLineNumbers import dynamic from "next/dynamic"; @@ -55,25 +49,88 @@ export default function App() { } ``` -Here is a working [demo](https://codesandbox.io/p/sandbox/excalidraw-with-next-dynamic-k8yjq2). +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: + + + + + ```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 ( +
+
+ ); + }; + export default ExcalidrawWrapper; + ``` + +
+ -2. Importing Excalidraw once **client** is rendered. + ```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 -```jsx showLineNumbers -import { useState, useEffect } from "react"; -export default function App() { - const [Excalidraw, setExcalidraw] = useState(null); - useEffect(() => { - import("@excalidraw/excalidraw").then((comp) => - setExcalidraw(comp.Excalidraw), + const ExcalidrawWrapper = dynamic( + async () => (await import("../excalidrawWrapper")).default, + { + ssr: false, + }, + ); + + export default function Page() { + return ( + ); - }, []); - return <>{Excalidraw && }; -} -``` + } + ``` + + + + + ```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 ( + + ); + } + ``` + + +
+ + +Here is a [source code](https://github.com/excalidraw/excalidraw/tree/master/examples/excalidraw/with-nextjs) for the example with app and pages router. You you can try it out [here](https://excalidraw-package-example-with-nextjs-gh6smrdnq-excalidraw.vercel.app/). -Here is a working [demo](https://codesandbox.io/p/sandbox/excalidraw-with-next-5xb3d) The `types` are available at `@excalidraw/excalidraw/types`, you can view [example for typescript](https://codesandbox.io/s/excalidraw-types-9h2dm)