Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: use LexicalCollaborationPlugin in nextjs #2696

Closed
cqh963852 opened this issue Jul 24, 2022 · 6 comments
Closed

Feature: use LexicalCollaborationPlugin in nextjs #2696

cqh963852 opened this issue Jul 24, 2022 · 6 comments
Labels
enhancement Improvement over existing feature

Comments

@cqh963852
Copy link

I am using nextjs with LexicalCollaborationPlugin.

But it will said WebSocket is not defined. It is related to ssr.

I tried mount the plugin at client side. It will said Hydration failed because the initial UI does not match what was rendered on the server.

Is there any way I can use CollaborationPlugin on nextjs?

@cqh963852 cqh963852 added the enhancement Improvement over existing feature label Jul 24, 2022
@cqh963852
Copy link
Author

import { CollaborationPlugin } from "@lexical/react/LexicalCollaborationPlugin";
import type { WebsocketProvider } from "y-websocket";
import type { Doc } from "yjs";

interface IProps {
  id: string;
  providerFactory: (
    id: string,
    yjsDocMap: Map<string, Doc>
  ) => WebsocketProvider;
  shouldBootstrap: boolean;
  username?: string;
}

const LexicalCollaborationPlugin = (props: IProps) => {
  return <CollaborationPlugin {...props} />;
};

export default LexicalCollaborationPlugin;
import { LexicalComposer } from "@lexical/react/LexicalComposer";
import { ContentEditable } from "@lexical/react/LexicalContentEditable";
import { PlainTextPlugin } from "@lexical/react/LexicalPlainTextPlugin";
import dynamic from "next/dynamic";

const LexicalCollaborationPlugin = dynamic(
  () => import("./LexicalCollaborationPlugin"),
  {
    ssr: false,
  }
);

import * as Y from "yjs";
import { WebsocketProvider } from "y-websocket";

const Editor = () => {
  return (
    <LexicalComposer
      initialConfig={{
        namespace: "test",
        onError: () => {},
      }}
    >
      <PlainTextPlugin
        contentEditable={<ContentEditable />}
        placeholder={<div>Enter some text...</div>}
      />
      <LexicalCollaborationPlugin
        id="yjs-plugin"
        providerFactory={(id, yjsDocMap) => {
          const doc = new Y.Doc();
          yjsDocMap.set(id, doc);

          const provider = new WebsocketProvider(
            "ws://localhost:1234",
            id,
            doc
          );

          return provider;
        }}
        shouldBootstrap={true}
      />
    </LexicalComposer>
  );
};

export default Editor;

I have create a custom component with no ssr dynamic import. It can resolve the problem

@cqh963852
Copy link
Author

With dynamic import, the project based on nextjs can send yjs msg to project based on vite which in offical playground.

But the project based on nextjs still can't apply yjs msg.

@lerik1408
Copy link

@cqh963852
This solution works for remix also. But I faced a problem. The text is duplicated. yjsDocMap doesn't have previous items. I can't get it via yjsDocMap.get(id) and load this document. Do you have the same problem?

@6peterlu
Copy link

6peterlu commented Dec 29, 2022

I'm getting the following stacktrace when using this solution with nextjs and vercel deployment:

"ReferenceError: Cannot access 'D' before initialization
    at Object.QP (https://www.umbra.page/_next/static/chunks/159.f9938be1d1917113.js:1:81706)
    at 6292 (https://www.umbra.page/_next/static/chunks/159.f9938be1d1917113.js:1:88843)
    at n (https://www.umbra.page/_next/static/chunks/webpack-5674241cb2eb00a4.js:1:134)
    at 8697 (https://www.umbra.page/_next/static/chunks/159.f9938be1d1917113.js:1:72640)
    at n (https://www.umbra.page/_next/static/chunks/webpack-5674241cb2eb00a4.js:1:134)
    at 8535 (https://www.umbra.page/_next/static/chunks/159.f9938be1d1917113.js:1:82245)
    at n (https://www.umbra.page/_next/static/chunks/webpack-5674241cb2eb00a4.js:1:134)
    at 3540 (https://www.umbra.page/_next/static/chunks/159.f9938be1d1917113.js:1:111102)
    at n (https://www.umbra.page/_next/static/chunks/webpack-5674241cb2eb00a4.js:1:134)
    at 3838 (https://www.umbra.page/_next/static/chunks/159.f9938be1d1917113.js:1:118310)"

Has anyone else encountered this?

@cqh963852
Copy link
Author

@cqh963852 This solution works for remix also. But I faced a problem. The text is duplicated. yjsDocMap doesn't have previous items. I can't get it via yjsDocMap.get(id) and load this document. Do you have the same problem?

I have meet problem like this. But not on lexical.

Due to there is no opportunity for initialization in decentralized collaboration. The document must start from empty.

If the initialization part is added, the collaboration will be repeated with the initialization and conflicts will occur.

My solution to this problem is to use a centralized initialization method.

While connect to the server, yjs sync document from server. Synchronization at this time can be regarded as an initialization action

@6peterlu
Copy link

I managed to upload sourcemaps for a more readable error:

ReferenceError: Cannot access 'C' before initialization
    at Object.QP (Skip.js:60:1)
    at 6292 (YArray.js:45:29)
    at l (bootstrap:21:1)
    at 8697 (ContentString.js:112:8)
    at l (bootstrap:21:1)
    at 8535 (Skip.js:60:1)
    at l (bootstrap:21:1)
    at 5021 (DeleteSet.js:325:1)
    at l (bootstrap:21:1)
    at 3838 (StructStore.js:261:5)

it clearly still is a result of the CollaborationPlugin :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improvement over existing feature
Projects
None yet
Development

No branches or pull requests

3 participants