fixed react-error with mdx on mobile (#4919)

Extracted mdx compilation logic to the server component to prevent
hydration bugs

<img width="538" alt="Screenshot 2024-04-11 at 14 03 36"
src="https://github.com/twentyhq/twenty/assets/102751374/53383da5-2e5d-4ab6-829c-550b8af2ca25">

Co-authored-by: Ady Beraud <a.beraud96@gmail.com>
This commit is contained in:
Ady Beraud
2024-04-12 10:20:11 +02:00
committed by GitHub
parent 990f9aeff4
commit 138fcbf45f
3 changed files with 42 additions and 25 deletions

View File

@ -1,10 +1,8 @@
'use client';
import { JSXElementConstructor, ReactElement } from 'react';
import styled from '@emotion/styled';
import { Gabarito } from 'next/font/google';
import { compileMDX } from 'next-mdx-remote/rsc';
import remarkBehead from 'remark-behead';
import gfm from 'remark-gfm';
import { Theme } from '@/app/_components/ui/theme/theme';
import { ReleaseNote } from '@/app/releases/api/route';
@ -91,24 +89,13 @@ const gabarito = Gabarito({
variable: '--font-gabarito',
});
export const Release = async ({ release }: { release: ReleaseNote }) => {
let mdxSource;
try {
mdxSource = await compileMDX({
source: release.content,
options: {
mdxOptions: {
development: process.env.NODE_ENV === 'development',
remarkPlugins: [gfm, [remarkBehead, { depth: 2 }]],
},
},
});
mdxSource = mdxSource.content;
} catch (error) {
console.error('An error occurred during MDX rendering:', error);
mdxSource = `<p>Oops! Something went wrong.</p> ${error}`;
}
export const Release = ({
release,
mdxReleaseContent,
}: {
release: ReleaseNote;
mdxReleaseContent: ReactElement<any, string | JSXElementConstructor<any>>;
}) => {
return (
<StyledContainer className={gabarito.className}>
<StyledVersion>
@ -119,8 +106,7 @@ export const Release = async ({ release }: { release: ReleaseNote }) => {
: release.date}
</StyledDate>
</StyledVersion>
<StlyedContent>{mdxSource}</StlyedContent>
<StlyedContent>{mdxReleaseContent}</StlyedContent>
</StyledContainer>
);
};

View File

@ -1,5 +1,9 @@
import { JSXElementConstructor, ReactElement } from 'react';
import fs from 'fs';
import matter from 'gray-matter';
import { compileMDX } from 'next-mdx-remote/rsc';
import remarkBehead from 'remark-behead';
import gfm from 'remark-gfm';
import { ReleaseNote } from '@/app/releases/api/route';
import { compareSemanticVersions } from '@/shared-utils/compareSemanticVersions';
@ -45,3 +49,23 @@ export async function getReleases(baseUrl?: string): Promise<ReleaseNote[]> {
return releasenotes;
}
export async function getMdxReleasesContent(
releases: ReleaseNote[],
): Promise<ReactElement<any, string | JSXElementConstructor<any>>[]> {
const mdxSourcesPromises = releases.map(async (release) => {
const mdxSource = await compileMDX<{ title: string; position?: number }>({
source: release.content,
options: {
parseFrontmatter: true,
mdxOptions: {
development: process.env.NODE_ENV === 'development',
remarkPlugins: [gfm, [remarkBehead, { depth: 2 }]],
},
},
});
return mdxSource.content;
});
return await Promise.all(mdxSourcesPromises);
}

View File

@ -5,7 +5,10 @@ import { Line } from '@/app/_components/releases/Line';
import { Release } from '@/app/_components/releases/Release';
import { Title } from '@/app/_components/releases/StyledTitle';
import { ContentContainer } from '@/app/_components/ui/layout/ContentContainer';
import { getReleases } from '@/app/releases/get-releases';
import {
getMdxReleasesContent,
getReleases,
} from '@/app/releases/get-releases';
export const metadata: Metadata = {
title: 'Twenty - Releases',
@ -14,6 +17,7 @@ export const metadata: Metadata = {
const Home = async () => {
const releases = await getReleases();
const mdxReleasesContent = await getMdxReleasesContent(releases);
return (
<ContentContainer>
@ -21,7 +25,10 @@ const Home = async () => {
{releases.map((note, index) => (
<React.Fragment key={note.slug}>
<Release release={note} />
<Release
release={note}
mdxReleaseContent={mdxReleasesContent[index]}
/>
{index != releases.length - 1 && <Line />}
</React.Fragment>
))}