如何在 Next.js 13 中使用上下文并仍然使用 Metadata API。

huangapple go评论59阅读模式
英文:

how to use context and still use metadata api inside next js 13

问题

I am unable to render layout.tsx with a default theme as the theme provider is needed and useContext is called. Therefore next js complains about not being able to run server-side. So I put the use client field into the document, and now the metadata tags won't load.

layout.tsx

'use client'

import { Metadata } from 'next'
export const metadata: Metadata = {
  title: {
    default: 'some title',
    template: '%s | some title'
  }
}

import { createTheme, ThemeProvider } from '@mui/material/styles'
const theme = createTheme({...})

# ...

export default ({children}: {children: React.ReactNode}) => (

    <ThemeProvider theme={theme}>
        <LocalizationProvider dateAdapter={AdapterDayjs}>
            <html>
                <body>{children}</body>
            </html>
        </LocalizationProvider>
    </ThemeProvider>
)
英文:

I am unable to render layout.tsx with a default theme as the theme provider is needed and useContext is called. Therefore next js complains about not being able to run server-side. So I put the use client field into the document, and now the metadata tags won't load.

layout.tsx

&#39;use client&#39;

import { Metadata } from &#39;next&#39;
export const metadata: Metadata = {
  title: {
    default: &#39;some title&#39;,
    template: &#39;%s | some title&#39;
  }
}

import { createTheme, ThemeProvider } from &#39;@mui/material/styles&#39;
const theme = createTheme({...

...

export default ({children}: {children: React.ReactNode}) =&gt; (

    &lt;ThemeProvider theme={theme}&gt;
        &lt;LocalizationProvider dateAdapter={AdapterDayjs}&gt;
            &lt;html&gt;
                &lt;body&gt;{children}&lt;/body&gt;
            &lt;/html&gt;
        &lt;/LocalizationProvider&gt;
    &lt;/ThemeProvider&gt;
)

答案1

得分: 2

Layout.tsx

import { Metadata } from 'next'

import RootLayout from './RootLayout'

export const metadata: Metadata = {
  title: {
    default: '某个标题',
    template: '%s | 某个标题'
  }
}

export default function Layout({ children }: LayoutProps) {
    return (
        <html lang="en">
            <body>
                <RootLayout>{children}</RootLayout>
            </body>
        </html>
    )
}

RootLayout.tsx

'use client'

import { createTheme, ThemeProvider } from '@mui/material/styles'
const theme = createTheme({})

export default function RootLayout({ children }: { children: React.ReactNode }) {
    return (
        <ThemeProvider theme={theme}>
            <LocalizationProvider dateAdapter={AdapterDayjs}>
                <html>
                    <body>{children}</body>
                </html>
            </LocalizationProvider>
        </ThemeProvider>
    )
}
英文:

You need to split them in 2 files simple, one client & another server

Layout.tsx

import { Metadata } from &#39;next&#39;

import RootLayout from &#39;./RootLayout&#39;

export const metadata: Metadata = {
  title: {
    default: &#39;some title&#39;,
    template: &#39;%s | some title&#39;
  }
}

export default function Layout({ children }: LayoutProps) {
	return (
		&lt;html lang=&quot;en&quot;&gt;
			&lt;body&gt;
				&lt;RootLayout&gt;{children}&lt;/RootLayout&gt;
			&lt;/body&gt;
		&lt;/html&gt;
	)
}

RootLayout.tsx

&#39;use client&#39;

import { createTheme, ThemeProvider } from &#39;@mui/material/styles&#39;
const theme = createTheme({})

export default RootLayout({children}: {children: React.ReactNode}) =&gt; (

    &lt;ThemeProvider theme={theme}&gt;
        &lt;LocalizationProvider dateAdapter={AdapterDayjs}&gt;
            &lt;html&gt;
                &lt;body&gt;{children}&lt;/body&gt;
            &lt;/html&gt;
        &lt;/LocalizationProvider&gt;
    &lt;/ThemeProvider&gt;
)

答案2

得分: 1

不要将您的布局设置为客户端组件,而是创建一个名为Provider的客户端组件,然后可以在您的布局中导入它。以下是一个示例:

"use client";

import { createTheme, ThemeProvider } from '@mui/material/styles'

interface Props extends React.PropsWithChildren {}

const theme = createTheme(/* ... */);

export default function Provider({ children }: Props) {
  return <ThemeProvider>{ children }</ThemeProvider>;
}
英文:

Do not make your layout a client component, rather create a client component called Provider that then can be imported in your layout. Heres an example:

&quot;use client&quot;;

import { createTheme, ThemeProvider } from &#39;@mui/material/styles&#39;

interface Props extends React.PropsWithChildren {}

const theme = createTheme(/* ... */);

export default function Provider({ children }: Props) {
  return &lt;ThemeProvider&gt;{ children }&lt;/ThemeProvider&gt;;
}

huangapple
  • 本文由 发表于 2023年6月6日 03:57:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76409624.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定