Skip to content
This repository has been archived by the owner on Jan 20, 2022. It is now read-only.

Content is not rendered when using SSR #303

Open
petrovalex opened this issue Oct 7, 2020 · 11 comments
Open

Content is not rendered when using SSR #303

petrovalex opened this issue Oct 7, 2020 · 11 comments
Labels
$$$ This issue is sponsored by Outline, optional payment is available – contact hello@getoutline.com enhancement New feature or request

Comments

@petrovalex
Copy link

Hello, trying to use this library with Nextjs, but the content is not getting rendered server side

Expected behavior
Content should be rendered

Version
11.0.1

@petrovalex petrovalex added the bug Something isn't working label Oct 7, 2020
@tommoor
Copy link
Member

tommoor commented Oct 7, 2020

Prosemirror does not support node, so to achieve this we'd have to write a renderer that emulates the output of Prosemirror – Remirror has done a good job of this, so it could be an inspiration for the work:

https://github.com/remirror/remirror/tree/master/@remirror/react-ssr

https://github.com/remirror/remirror/blob/997eb56a49ad653544fcd00b83e394e63df3a116/packages/%40remirror/react/src/renderers/react-serializer.tsx#L146

@petrovalex
Copy link
Author

Alright, thanks!

@tommoor tommoor added the $$$ This issue is sponsored by Outline, optional payment is available – contact hello@getoutline.com label Oct 20, 2020
@micheleriva
Copy link

Hi @tommoor,
I get your point about Remirror, but I would expect it to work using dynamic imports with Next.js:

const Editor = dynamic(() => import('rich-markdown-editor'), {ssr: false})

const MySSRComponent = () => {

return (
  <>
    {
        !process.browser
        ? null
        : (
              <Editor
              id={/*  my id */}
              defaultValue='Default value'
              placeholder='Placeholder'
              onChange={console.log}
             />
           ) 
    }
  </>
  )
}

but it's not working anyway... any idea on that?

@tommoor
Copy link
Member

tommoor commented Oct 23, 2020

I would expect it to work using dynamic imports with Next.js

Me too, Next must be rendering that on the server side?

@micheleriva
Copy link

I would expect it to work using dynamic imports with Next.js

Me too, Next must be rendering that on the server side?

I've specified {ssr: false} to the dynamic import options and checked if process.browser was truthy on the client side before rendering, but it's not showing up

@tarsenidze
Copy link

You can create a component outside the "Page" folder and then import it dynamically inside.

import dynamic from "next/dynamic";

const Example = dynamic(() => import("../Components/<componentName>.js"), { ssr: false });

export default Example;

"Example" in this case is from the example/src/index.js file

@luaneko
Copy link

luaneko commented Jan 31, 2021

@tarsenidze

You can create a component outside the "Page" folder and then import it dynamically inside.

Does not work.


After lots of trial and error, I think I found a workaround that seems to work quite reliably.

import React, { memo, useEffect, useState } from "react";
import RichMarkdownEditor from "rich-markdown-editor";
import { Router } from "next/router";

const MarkdownDisplay = ({ value }: { value: string }) => {
  const [render, setRender] = useState(false);

  useEffect(() => {
    const handle = () => {
      // it doesn't work without setTimeout but I don't know why
      setTimeout(() => setRender(true));
    };

    // bind to window load event for ssr and route change event for csr
    window.addEventListener("load", handle);
    Router.events.on("routeChangeComplete", handle);

    return () => {
      window.removeEventListener("load", handle);
      Router.events.off("routeChangeComplete", handle);
    };
  }, []);

  // render the editor initially with an empty string until the document is completely loaded
  // this is important because the change in value causes prosemirror to rerender the dom correctly on the client later
  return <RichMarkdownEditor value={render ? value : ""} onChange={() => {}} readOnly />;
};

export default memo(MarkdownDisplay);

This workaround should make the editor render correctly, but only on the client. It won't be visible immediately when the page is refreshed, so there will be some waiting time for the document to load until you see something. I really find it quite unfortunate that we can't take advantage of server side rendering with this editor.

@tommoor tommoor added enhancement New feature or request and removed bug Something isn't working labels Feb 13, 2021
@nikita2423
Copy link

Any update on this ?

@tommoor
Copy link
Member

tommoor commented Apr 15, 2021

I'm not planning on working on this at the moment, my applications do not use SSR. However if someone else wants to enable this functionality a PR would be happily accepted

@MonstraG
Copy link

I didn't show (loading ? <Spinner/> : <Editor/>) the Markdown editor before routeChangeComplete event, this worked instead (even with navigating between two [slug].tsx dynamic pages containing this component):

const Editor: FC<{ value: string }> = ({ value }) => {
  const [render, setRender] = useState(false);
  useEffect(() => {
    setRender(true);
  }, []);

  return (
    <RichMarkdownEditor value={render ? value : undefined} />
  );
};

@seeARMS
Copy link

seeARMS commented Jul 29, 2021

I wanted my content to get rendered as a static page (ie, rendered at build-time), so I used the react-markdown library to display the content on the server-side (since it supports SSR), then I swapped it with rich-markdown-editor on client render. This is hacky, and the initial styles that react-markdown uses are not great so there's a flicker when rich-markdown-editor is loading, but at least the content is being rendered statically.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
$$$ This issue is sponsored by Outline, optional payment is available – contact hello@getoutline.com enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants