概要
v1.0 で導入された新機能に関する記事です。新機能一覧:
- テーマカラー
- Xdm MDX コンパイラー
- 目次コンポーネント
- レイアウト
- アナリティクス
- ブログコメントシステム
- 複数著者
- コードブロックのコピーボタン
- 行ハイライトと行番号
- ニュースレターコンポーネント (v1.1.3)
- 参考文献と引用 (v1.2.1)
- セルフホストフォント (v1.5.0)
- アップグレードガイド
すべての新機能が追加されたにもかかわらず、初回ロード JS は 43kB から 39kB に削減されました! 1
v0 バージョンのテンプレートから移行する場合は、以下のアップグレードガイドを参照してください。
テーマカラー
Tailwind 設定ファイルのプライマリー属性を変更することで、テーマカラーを簡単にカスタマイズできます:
theme: {
colors: {
primary: colors.teal,
gray: colors.neutral,
...
}
...
}
プライマリーカラー属性には、50、100、200 ... 900 のキーと対応するカラーコード値を持つオブジェクトを割り当てる必要があります。
Tailwind には、ウェブサイトのテーマに利用できる優れたデフォルトカラーパレットが含まれています。オプションの全範囲についてはカラーカスタマイズのドキュメントページをご確認ください。
v1 から移行しますか?primary を colors.sky(Tailwind 2.2.2 以上、それ以前は colors.lightBlue)に設定し、gray を colors.gray に変更することで、以前のテーマに戻すことができます。
v1.1.2 以降では、css/prism.css スタイルシートを変更することでコードブロックのスタイルも簡単にカスタマイズできます。トークンのクラス名は prismjs と互換性があるため、prismjs スタイルシート(例:prism themes)からトークンスタイルをコピーして適用できます。
Xdm MDX コンパイラー
MDX バンドラーを next-mdx-remote から mdx-bundler に切り替えました。 内部では最新の micromark 3、remark、rehype ライブラリを使用する xdm を利用しています。
警告: カスタムの remark または rehype ライブラリを使用していた場合は、micromark 3 互換のものにアップグレードしてください。アップグレードする場合は、過去の依存関係の問題を回避するために node_modules と package-lock.json を削除してください。
xdm は、next-mdx-remote が内部で使用するコンパイラーである @mdx-js/mdx に対して複数の改善を含んでいますが、一部の破壊的な動作変更がある可能性があります。 マークダウンの出力を確認して検証してください。
新たに可能になったことには、import 構文を使用して mdx ファイルにコンポーネントを直接読み込んだり、ビルドステップでコンパイル・バンドルされる js コードを含めたりすることが挙げられます。
例えば、以下の jsx スニペットを MDX ファイルで直接使用して、ページタイトルコンポーネントをレンダリングできます:
// Or import PageTitle from './components/PageTitle.js' if you are using js
import PageTitle from './components/PageTitle.tsx'
;<PageTitle> Using JSX components in MDX </PageTitle>
デフォルト設定では、すべてのコンポーネントは components ディレクトリを基準に解決されます。
注意:
外部画像ローダーを必要とするコンポーネントには、追加の esbuild 設定も必要です。
各 mdx ファイルは独立してビルドされるため、Nextjs の Link コンポーネントのようにグローバルなアプリケーション状態やライフサイクルに依存するコンポーネントも、このセットアップでは動作しません。
そのようなケースでは、コンポーネントの置換を使用する方が良いでしょう。
目次コンポーネント
Docusaurus と Gatsby の gatsby-remark-table-of-contents に触発され、
ドキュメントのすべてのトップレベル見出しを含む toc 変数が MDX ファイルに渡され、適宜スタイリングできます。
目次(TOC)の生成を簡単にするために、既存の TOCInline コンポーネントを使用できます。
例えば、この記事の TOC は以下のコードで生成されました:
<TOCInline toc={props.toc} exclude="Overview" toHeading={2} />
fromHeading と toHeading プロパティを設定して表示する見出しをカスタマイズしたり、exclude プロパティに文字列または文字列配列を渡して特定の見出しを除外したりできます。デフォルトでは、深さ 3 以下のすべての見出しがインデントされます。これは indentDepth プロパティを変更することで設定できます。
asDisclosure プロパティを使用して、TOC を展開可能なディスクロージャー要素内にレンダリングできます。
以下はディスクロージャー要素内にレンダリングされた完全な TOC です。
<TOCInline toc={props.toc} asDisclosure />
Table of Contents
レイアウト
フロントマターフィールドを設定することで、mdx ブログコンテンツをレイアウトコンポーネントにマッピングできます。例えば、この記事は新しい PostSimple レイアウトで書かれています!
新しいテンプレートの追加
レイアウトテンプレートは ./layouts フォルダーに格納されています。マークダウンコンテンツにマッピングしたい React コンポーネントをこのフォルダーに追加できます。
コンポーネントのファイル名は、マークダウンのフロントマターの layout フィールドで指定されたものと一致する必要があります。
唯一の必須フィールドは、レンダリングされた MDX コンテンツを含む children ですが、通常は frontMatter の内容も渡してテンプレート内でレンダリングしたいでしょう。
テンプレートで他のフィールドを受け取るように設定できます。例については PostLayout コンポーネントを参照してください。
以下は、さらにカスタマイズ可能なレイアウトの例です:
export default function ExampleLayout({ frontMatter, children }) {
const { date, title } = frontMatter
return (
<SectionContainer>
<div>{date}</div>
<h1>{title}</h1>
<div>{children}</div>
</SectionContainer>
)
}
ブログ記事のフロントマター設定
layout フロントマターフィールドを使用して、マークダウン記事をマッピングするテンプレートを指定します。この記事のフロントマターは以下のようになっています:
---
title: 'New features in v1'
date: '2021-05-26 '
tags: ['next-js', 'tailwind', 'guide']
draft: false
summary: 'Introducing the new layout features - you can map mdx blog content to layout components by configuring the frontmatter field'
layout: PostSimple
---
DEFAULT_LAYOUT 変数を変更することで、各ページセクションのデフォルトレイアウトを設定できます。
ブログ記事ページの DEFAULT_LAYOUT は PostLayout に設定されています。
拡張
layout は MDX コンテンツ全体をラップする wrapper にマッピングされます。
export const MDXComponents = {
Image,
a: CustomLink,
pre: Pre,
wrapper: ({ components, layout, ...rest }) => {
const Layout = require(`../layouts/${layout}`).default
return <Layout {...rest} />
},
}
export const MDXLayoutRenderer = ({ layout, mdxSource, ...rest }) => {
const MDXLayout = useMemo(() => getMDXComponent(mdxSource), [mdxSource])
return <MDXLayout layout={layout} components={MDXComponents} {...rest} />
}
目的のレイアウトにマッピングするレイアウト名を受け入れたいページで MDXLayoutRenderer コンポーネントを使用します。
レイアウトフォルダーからレイアウト名を渡す必要があります(完全一致が必要です)。
アナリティクス
テンプレートは plausible、simple analytics、Google Analytics をサポートしています。
siteMetadata.js に目的のアナリティクスプロバイダーに対応する設定を記述してください。
analytics: {
// supports plausible, simpleAnalytics or googleAnalytics
plausibleDataDomain: '', // e.g. tailwind-nextjs-starter-blog.vercel.app
simpleAnalytics: false, // true or false
googleAnalyticsId: '', // e.g. UA-000000-2 or G-XXXXXXX
},
カスタムイベントもサポートされています。@components/analytics/[ANALYTICS-PROVIDER] ファイルから logEvent 関数をインポートし、関心のあるイベントのトリガー時に呼び出すことができます。注意:アナリティクスプロバイダーによっては追加設定が必要な場合があります。詳細は各プロバイダーの公式ドキュメントを確認してください。
ブログコメントシステム
giscus、utterances、disqus のサポートも追加しました。
有効にするには、設定ファイルで指定されているように siteMetadata.js の comments プロパティに目的のプロバイダーと設定を記述するだけです。
comment: {
// Select a provider and use the environment variables associated to it
// https://vercel.com/docs/environment-variables
provider: 'giscus', // supported providers: giscus, utterances, disqus
giscusConfig: {
// Visit the link below, and follow the steps in the 'configuration' section
// https://giscus.app/
repo: process.env.NEXT_PUBLIC_GISCUS_REPO,
repositoryId: process.env.NEXT_PUBLIC_GISCUS_REPOSITORY_ID,
category: process.env.NEXT_PUBLIC_GISCUS_CATEGORY,
categoryId: process.env.NEXT_PUBLIC_GISCUS_CATEGORY_ID,
mapping: 'pathname', // supported options: pathname, url, title
reactions: '1', // Emoji reactions: 1 = enable / 0 = disable
// Send discussion metadata periodically to the parent window: 1 = enable / 0 = disable
metadata: '0',
// theme example: light, dark, dark_dimmed, dark_high_contrast
// transparent_dark, preferred_color_scheme, custom
theme: 'light',
// theme when dark mode
darkTheme: 'transparent_dark',
// If the theme option above is set to 'custom`
// please provide a link below to your custom theme css file.
// example: https://giscus.app/themes/custom_example.css
themeURL: '',
},
utterancesConfig: {
// Visit the link below, and follow the steps in the 'configuration' section
// https://utteranc.es/
repo: process.env.NEXT_PUBLIC_UTTERANCES_REPO,
issueTerm: '', // supported options: pathname, url, title
label: '', // label (optional): Comment 💬
// theme example: github-light, github-dark, preferred-color-scheme
// github-dark-orange, icy-dark, dark-blue, photon-dark, boxy-light
theme: '',
// theme when dark mode
darkTheme: '',
},
disqus: {
// https://help.disqus.com/en/articles/1717111-what-s-a-shortname
shortname: process.env.NEXT_PUBLIC_DISQUS_SHORTNAME,
},
},
複数著者
著者情報は siteMetadata.js から分離され、独自の data/authors フォルダーにマークダウンファイルとして格納されるようになりました。最低限、著者情報を含む default.md ファイルが必要です。必要に応じて追加ファイルを作成でき、ファイル名が著者への参照として使用されます。
著者のマークダウンファイルは以下のようになります:
---
name: Tails Azimuth
avatar: /static/images/avatar.png
occupation: Professor of Atmospheric Science
company: Stanford University
email: address@yoursite.com
twitter: https://twitter.com/Twitter
linkedin: https://www.linkedin.com
github: https://github.com
---
A long description of yourself...
この情報はテンプレート内の複数の場所で使用できます。例えば、ページの about セクションでは、以下のコードでデフォルトの著者情報を取得します:
const authorDetails = await getFileBySlug('authors', ['default'])
これは AuthorLayout テンプレートでレンダリングされます。
ブログ記事での複数著者
ブログ記事のフロントマターは、オプションの authors 配列フィールドを受け付けます。フィールドが指定されていない場合は、デフォルトの著者が使用されます。記事に関連付ける複数の著者をレンダリングするには、著者の配列を渡すだけです。
例えば、以下のフロントマターは data/authors/default.md と data/authors/sparrowhawk.md で指定された著者を表示します。
title: 'My first post'
date: '2021-01-12'
draft: false
summary: 'My first post'
authors: ['default', 'sparrowhawk']
複数著者の記事のデモは Introducing Tailwind Nextjs Starter Blog の記事で確認できます。
コードブロックのコピーボタン
コードブロックにマウスを合わせると、GitHub スタイルのコピーボタンが表示されます!./components/Pre.js を変更してさらにカスタマイズできます。
このコンポーネントは MDXComponents に渡され、すべての pre ブロックを変更します。
行ハイライトと行番号
新しい rehype-prism-plus プラグインにより、行ハイライトと行番号がすぐに使えるようになりました。
以下の javascript コードブロック:
js {1, 3-4} showLineNumbers
var num1, num2, sum
num1 = prompt('Enter first number')
num2 = prompt('Enter second number')
sum = parseInt(num1) + parseInt(num2) // "+" means "add"
alert('Sum = ' + sum) // "+" means combine into a string
は以下のように表示されます:
var num1, num2, sum
num1 = prompt('Enter first number')
num2 = prompt('Enter second number')
sum = parseInt(num1) + parseInt(num2) // "+" means "add"
alert('Sum = ' + sum) // "+" means combine into a string
スタイルを変更するには、prism.css ファイルの以下のクラスセレクターを変更してください:
.code-highlight {
@apply float-left min-w-full;
}
.code-line {
@apply -mx-4 block border-l-4 border-opacity-0 pl-4 pr-4;
}
.code-line.inserted {
@apply bg-green-500 bg-opacity-20;
}
.code-line.deleted {
@apply bg-red-500 bg-opacity-20;
}
.highlight-line {
@apply -mx-4 border-l-4 border-primary-500 bg-gray-700 bg-opacity-50;
}
.line-number::before {
@apply -ml-2 mr-4 inline-block w-4 text-right text-gray-400;
content: attr(line);
}
ニュースレターコンポーネント (v1.1.3)
v1.1.3 で導入されたニュースレターコンポーネントは、オーディエンスを構築する簡単な方法を提供します。以下のプロバイダーと統合できます:
使用するには、設定ファイルで使用しているプロバイダーを指定し、必要な環境変数を .env ファイルに追加してください。
必要な変数の詳細については .env.sample を確認してください。
デフォルトの NewsletterForm と BlogNewsletterForm コンポーネントの 2 つがエクスポートされます。BlogNewsletterForm は MDX コンポーネントとしても渡され、ブログ記事内で使用できます:
<BlogNewsletterForm title="Like what you are reading?" />
このコンポーネントは nextjs の API routes に依存しており、nextjs のサーバーサイドインスタンスのセットアップが必要で、100% 静的サイトエクスポートとは互換性がありません。ユーザーはセルフホストするか、この機能をサポートする Vercel や Netlify などの互換プラットフォームを使用する必要があります。
静的サイト互換の代替手段として、ニュースレターコンポーネントのルートをフォーム API エンドポイントプロバイダーに置き換えることができます。
参考文献と引用 (v1.2.1)
v1.2.1 では、rehype-citation プラグインが xdm 処理パイプラインに追加されました。これにより、既存の bibtex または CSL-json ファイルから簡単に引用をフォーマットし、参考文献を挿入できます。
例えば、以下のマークダウンコードサンプル:
Standard citation [@Nash1950]
In-text citations e.g. @Nash1951
Multiple citations [see @Nash1950; @Nash1951, page 50]
**References:**
[^ref]
は以下のようにレンダリングされます:
Standard citation [@Nash1950] In-text citations e.g. @Nash1951 Multiple citations [see @Nash1950; @Nash1951, page 50]
References:
[^ref]
参考文献はドキュメントの末尾に挿入されますが、目的の場所に [^Ref] タグを指定することで上書きできます。
プラグインは APA 引用形式を使用しますが、'apa'、'vancouver'、'harvard1'、'chicago'、'mla'、またはユーザー指定の CSL ファイルへのパスもサポートしています。
設定オプションの詳細については rehype-citation readme を参照してください。
セルフホストフォント (v1.5.0)
Google フォントは Fontsource のセルフホストフォントに置き換えられました。これにより以下のメリットが得られます:
セルフホスティングは大幅なパフォーマンス向上をもたらします。Google Fonts などのホスティングサービスからフォントを読み込むと、追加の(レンダリングブロッキング)ネットワークリクエストが発生するためです。参考までに、シンプルなウェブサイトでは視覚的な読み込み時間が 2 倍になることが確認されています。
フォントのバージョンが固定されます。Google はフォントの更新を予告なく配信することがあり、本番プロジェクトに影響を与える可能性があります。フォントを他の NPM 依存関係と同様に管理できます。
プライバシーへのコミットメント。Google はフォントの使用状況を追跡しており、プライバシーを非常に重視する方にとっては、セルフホスティングが代替手段となります。
これにより、フォントバンドルが小さくなり、読み込み時間が 0.1 秒速くなります(webpagetest 比較)。
デフォルトの Inter フォントを変更するには:
- お好みのフォントをインストール -
npm install -save @fontsource/<font-name> pages/_app.jsのインポートを更新 -import '@fontsource/<font-name>.css'- Tailwind CSS 設定ファイルの
fontfamilyプロパティを更新
アップグレードガイド
v0 から v1 へは、レイアウトのサポートや新しい mdx エンジンなど、コードの大部分が変更されています。
以前のバージョンが要件を満たしている場合は変更する必要はなく、すべてを移行するよりも、関心のあるコンポーネントの変更を既存のブログにコピーする方が簡単かもしれません。
それでも移行する場合で、テンプレートをあまり変更していない場合は、新しいバージョンをクローンしてブログ記事を新しいテンプレートにコピーできます。
もう 1 つの方法は、以下のコードで最新のテンプレートバージョンをプルすることです:
git remote add template git@github.com:timlrx/tailwind-nextjs-starter-blog.git
git pull template v1 --allow-unrelated-histories
rm -rf node_modules
このコミットで、私の個人ブログでのそのような移行の例を確認できます。
v1 では Vercel でのビルドの問題を回避するために、index.xml ではなく feed.xml を使用しています。移行する場合は、以下のように next.config.js にリダイレクトを追加してください:
async redirects() {
return [
{
source: '/:path/index.xml',
destination: '/:path/feed.xml',
permanent: true,
}
]
}
Footnotes
-
Nextjs 12 の新しい変更により、初回ロード JS は 45kB に増加しました。 ↩