Nextra 3.0 がリリースされました。 もっと読む
ドキュメントカスタムテーマ

カスタムテーマ

Nextra のテーマはレイアウトのように機能し、すべてのページのラッパーとしてレンダリングされます。このドキュメントでは、カスタムテーマを作成するプロセスを説明します。

オプションで、以下の手順に従って、例をデプロイしてさらに構築することができます。

カスタムテーマの作成

テーマを使用するように Nextra を設定

まず、Nextra に公式のテーマではなく、カスタムのテーマファイルを使用するように指示する必要があります。Next.js の設定で、テーマファイルへのパスを Nextra プラグインに渡すことができます。

next.config.mjs
import nextra from 'nextra'
 
const withNextra = nextra({
  theme: './theme.tsx'
})
 
// If you have other Next.js configurations, you can pass them as the parameter:
// export default withNextra({ /* other next.js config */ })

基本的なテーマの作成

これでテーマの作業を開始できます!ルートディレクトリに、対応する theme.tsx ファイルを基本的な内容で作成します。

theme.tsx
import type { NextraThemeLayoutProps } from 'nextra'
 
export default function Layout({ children }: NextraThemeLayoutProps) {
  return (
    <div>
      <h1>My Theme</h1>
      <div style={{ border: '1px solid' }}>{children}</div>
    </div>
  )
}

これは、現在のページの MDX コンテンツである children プロパティを受け取り、コンテンツの周りに他の要素をラップします。テーマを作成したら、pages/index.mdx として MDX ファイルを追加するだけで、結果を確認できます。

Custom theme

テーマレイアウト内では、CSS インポートやその他の方法でスタイルを設定できます。 useRouterHead などの Next.js フックも利用できます。

アクティブなページのメタデータをレンダリング

children 以外にも、他の便利なプロパティがテーマレイアウトに渡されます。 pageOpts プロパティを使用すると、テーマはページのメタ情報にアクセスできます。

たとえば、これらの機能を実装してみましょう。

  • <title> でページタイトルをレンダリングします。
  • MDX の <Wrapper> コンポーネントを介して簡単な目次を表示します。
  • フロントマターを介して og:image のメタタグを追加します。
theme.tsx
import Head from 'next/head'
import type { NextraThemeLayoutProps } from 'nextra'
import { MDXProvider } from 'nextra/mdx'
 
export default function Layout({ children, pageOpts }: NextraThemeLayoutProps) {
  const { title, frontMatter } = pageOpts
 
  return (
    <>
      <Head>
        <title>{title}</title>
        <meta name="og:image" content={frontMatter.image} />
      </Head>
      <MDXProvider components={{ wrapper: MyWrapper }}>{children}</MDXProvider>
    </>
  )
}
 
function MyWrapper({ children, toc }) {
  return (
    <>
      <h1>My Theme</h1>
      Table of Contents:
      <ul>
        {toc.map(heading => (
          <li key={heading.value}>{heading.value}</li>
        ))}
      </ul>
      <div style={{ border: '1px solid' }}>{children}</div>
    </>
  )
}

サイト全体のページマップを使用

次に、現在のページだけでなく他のページの情報を必要とするサイドバーやナビゲーションバーのようなものをレンダリングしたい場合は、pageMap 値を使用できます。

たとえば、トップレベルのすべてのページを含むシンプルなナビゲーションリストをレンダリングできます。

theme.tsx
import Link from 'next/link'
import type { NextraThemeLayoutProps } from 'nextra'
 
export default function Layout({ children, pageOpts }: NextraThemeLayoutProps) {
  const { pageMap } = pageOpts
 
  return (
    <div>
      <h1>My Theme</h1>
      {pageMap.map(item => {
        if ('route' in item && !('children' in item)) {
          return (
            <Link key={item.name} href={item.route}>
              {item.route}
            </Link>
          )
        }
      })}
      <div style={{ border: '1px solid' }}>{children}</div>
    </div>
  )
}

Folder (ディレクトリ用) や Meta (_meta.js ファイル用) など、他のアイテムの種類もあります。すべてのアイテムは型付けされているため、プロパティを簡単に把握できます。

高度な使用法

⚠️

高度な使用法に関するドキュメントは作成中です。