
Next.jsとWordPressでヘッドレスCMSのサイトを作成する#3:メタ情報設定・ファイル最適化・ステート管理
今回の記事でも引き続きNext.jsでヘッドレスCMSのサイトを作成していきます、前回でコーディング環境が構築され、共通のコンポーネント作成まで進んでいるので、続いてはサイト内でのメタ情報設定やファイル最適化などの基本的な共通処理などを用意していきます。
(過去の参考記事もどうぞ)
Next.jsとWordPressでヘッドレスCMSのサイトを作成する#2:コーディング環境の構築
Next.jsとWordPressでヘッドレスCMSのサイトを作成する#1:インストール・導入
今回はサイト内で扱う基本的な共通処理について実装していきました。Next.jsにはさまざまなAPIが用意されており、サイトのパフォーマンス向上に役立つ最適化なども簡単にできますのでぜひ活用していきたいですね。
1. サイトメタデータの設定(MetadataAPI)
Page RouterではHeadコンポーネントとつかってhead要素内のタグを出力していましたが、App Routerでは「MetadataAPI」をつかって自動的にメタタグを出力していきます。まずはメタデータをエクスポートするためのスクリプトを用意します。各オプションはサイトにあわせて必要なものを追記していきます。URLについては事前に環境変数を切り分けているので、それぞれ環境ごとの値が入るようにしています。 【/src/features/siteMeta.ts】import type { Metadata } from 'next';
export const SiteMeta: Metadata = {
viewport: {
width: 'device-width',
initialScale: 1
},
title: {
default: `${process.env.SITENAME}`,
template: `%s | ${process.env.SITENAME}`
},
description: `${process.env.DESCRIPTION}`,
robots: {
index: true,
follow: true
},
icons: {
icon: `${process.env.ENVURL}/favicon.ico`,
apple: `${process.env.ENVURL}/public/assets/images/****.png`
},
openGraph: {
type: 'website',
url: `${process.env.ENVURL}`,
title: {
default: `${process.env.SITENAME}`,
template: `%s | ${process.env.SITENAME}`
},
description: `${process.env.DESCRIPTION}`,
siteName: `${process.env.SITENAME}`,
locale: 'ja_JP',
images: [{ url: `${process.env.ENVURL}/public/assets/images/****.png` }]
},
verification: {
google: '********'
},
formatDetection: {
telephone: false,
address: false,
email: false
},
.....
};
作成した上記のスクリプトはテンプレート側でインポートしていきます。appディレクトリ直下のlayout.tsxで読み込み、共通の設定としてデフォルトで値が設定されるようにします。なお、動的に変更されるページについては上書きで対応していきます。
【/src/app/layout.tsx】
import type { Metadata } from 'next';
import { SiteMeta } from '@/features/siteMeta';
import Header from '@/components/Header';
import Footer from '@/components/Footer';
export const metadata: Metadata = SiteMeta;
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ja">
<body>
<Header />
{children}
<Footer />
</body>
</html>
);
};
2. フォントの最適化(next/font)
Next.jsにはWebフォントの最適化を行う機能が提供されています。この機能を使うことでフォントデータがセルフホスティングされ、ページの読み込み速度などのパフォーマンスを向上させていきます。ここではGoogleフォントとローカルに配置する別のWebフォントを使う例をみていきます。まずはフォント用のスクリプトを用意します。 【/src/features/fonts.ts】import { Noto_Sans_JP } from 'next/font/google';
import localFont from 'next/font/local';
// google fonts
export const notoSansJP = Noto_Sans_JP({
subsets: ['latin'],
variable: '--font-noto-sans-jp',
weight: 'variable',
display: 'swap',
preload: true
});
// localhost fonts
export const textaAlt = localFont({
variable: '--font-texta-alt',
src: [
{
path: '../../../public/assets/fonts/TextaAlt-Thin.woff2',
weight: '100',
style: 'normal'
},
{
path: '../../../public/assets/fonts/TextaAlt-Light.woff2',
weight: '200',
style: 'normal'
},
{
path: '../../../public/assets/fonts/TextaAlt-Book.woff2',
weight: '300',
style: 'normal'
},
{
path: '../../../public/assets/fonts/TextaAlt-Regular.woff2',
weight: '400',
style: 'normal'
},
{
path: '../../../public/assets/fonts/TextaAlt-Medium.woff2',
weight: '500',
style: 'normal'
},
{
path: '../../../public/assets/fonts/TextaAlt-Bold.woff2',
weight: '700',
style: 'normal'
},
{
path: '../../../public/assets/fonts/TextaAlt-Heavy.woff2',
weight: '800',
style: 'normal'
},
{
path: '../../../public/assets/fonts/TextaAlt-Black.woff2',
weight: '900',
style: 'normal'
},
]
});
重要なのはvariableのキーでCSS変数として扱えるようにしておくことです。後はレイアウトやページコンポーネントでこれを読み込み、CSSで設定することでフォントが適用されるようになります。
【/src/app/layout.tsx】
import type { Metadata } from 'next';
import '@/styles/main.scss';
import { SiteMeta } from '@/features/siteMeta';
import { notoSansJP, textaAlt } from '@/features/fonts';
import Header from '@/components/Header';
import Footer from '@/components/Footer';
export const metadata: Metadata = SiteMeta;
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ja">
<body className={`${textaAlt.variable} ${notoSansJP.variable}`}>
<Header />
{children}
<Footer />
</body>
</html>
);
};
3. ステートの管理(useContext)
アプリの状態管理についてはいろんなライブラリも存在しますが、今回はシンプルに扱うことのできるReactにデフォルトで用意されている「useContext」を使います。一般的なウェブサイトであればあまり必要ないかもしれませんが、ここではページメニューの表示状態や、サイトテーマの切り替えを例にみていきます。まずはストア用にデータを定義するスクリプトを用意します。初期値の設定やコンテキストをカスタムフックとして扱えるようにエクスポートしていきます。 【/src/store/siteContext.ts】'use client';
import { createContext, useContext } from 'react';
export type stateType = {
currentTheme: 'light' | 'dark';
isMenuOpen: boolean;
};
export type siteContextType = {
state: stateType;
setState: React.Dispatch<React.SetStateAction<stateType>>;
};
export const defaultState: stateType = {
currentTheme: 'light',
isMenuOpen: false
};
export const SiteContext = createContext<siteContextType>({
state: defaultState,
setState: () => {}
});
export const useSiteContext = () => useContext(SiteContext);
作成したコンテキストを受け取るプロバイダー用のコンポーネントを作成します。また、このコンポーネントでステートの値を更新できるように、ステートの値とあわせて更新するための処理を受け渡すようにしておきます。
【/src/provider/SiteProvider.tsx】
'use client';
import { useState } from 'react';
import { SiteContext, defaultState, stateType } from '@/store/siteContext';
const SiteProvider = ({ children }: { children: React.ReactNode }) => {
const [data, setData] = useState<stateType>(defaultState);
const contextValue = {
state: data,
setState: setData
};
return <SiteContext.Provider value={contextValue}>{children}</SiteContext.Provider>;
};
export default SiteProvider;
これでステートを扱いたいコンポーネントをプロバイダー用のコンポーネントで囲むことで、囲まれたコンポーネント内でステートの値を参照したり更新することができるようになります。ここではレイアウト用コンポーネント内で扱うことでサイト全体で参照できるようにしています。
【/src/app/layout.tsx】
import type { Metadata } from 'next';
import '@/styles/main.scss';
import { SiteMeta } from '@/features/siteMeta';
import { notoSansJP, textaAlt } from '@/features/fonts';
import Header from '@/components/Header';
import Footer from '@/components/Footer';
import SiteProvider from '@/provider/SiteProvider';
export const metadata: Metadata = SiteMeta;
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ja">
<body className={`${textaAlt.variable} ${notoSansJP.variable}`}>
<SiteStateProvider>
<Header />
{children}
<Footer />
</SiteStateProvider>
</body>
</html>
);
};
では実際にコンポーネントからステートの値を更新してみます。下記はページメニューの表示状態を更新する処理を例にみていきます。まずはステートの値を更新するためのカスタムフックを作成します。こうすることでコンポーネントから簡単に呼び出せるようにしておきます。
【/src/hooks/toggleMenu.ts】
'use client';
import { useSiteContext } from '@/store/siteContext';
export const useToggleMenu = () => {
const { state, setState } = useSiteContext();
const toggle = () =>
setState({
currentTheme: state.currentTheme,
isMenuOpen: !state.isMenuOpen
});
return { toggle };
};
コンポーネント側でカスタムフックを呼び出し、ステートの値を更新するように処理を実行します。
【/src/components/MenuButton.tsx】
'use client';
import { useToggleMenu } from '@/hooks/toggleMenu';
const MenuButton: React.FC = () => {
const { toggle } = useToggleMenu();
return (
<>
<button type="button" onClick={toggle}>
menu
</button>
</>
);
};
export default MenuButton;
後はページメニューのコンポーネント側でステートの値を参照し、値によって表示非表示を切り替えられるように対応しておきます。このようにしてサイト内で状態管理を扱っていきます。
4. 画像の最適化(next/image)
Next.jsには他にもローカル参照の画像ファイルを最適化する機能もあります。サイズの調整やレイアウトシフトへの対応、レスポンシブでのサイズ調整など、いろんなオプションが用意されており、必要にあわせて設定していきます。 【/src/components/Header.tsx】'use client';
import Image from 'next/image';
const Header: React.FC = () => {
return (
<header>
<Image
src={'/assets/images/logo.png'}
width={500}
height={200}
alt="example logo"
quality={75}
sizes='(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw'
/>
</header>
);
};
export default Header;
今回はサイト内で扱う基本的な共通処理について実装していきました。Next.jsにはさまざまなAPIが用意されており、サイトのパフォーマンス向上に役立つ最適化なども簡単にできますのでぜひ活用していきたいですね。
categories
- WordPress(61)
- JavaScript(49)
- Vue.js(48)
- CSS(46)
- jQuery(34)
- Nuxt.js(22)
- Sass(21)
- Gulp(17)
- webpack(16)
- PHP(14)
- HTML(14)
- GSAP(11)
- React(10)
- Vite(9)
- Pug(9)
- Laravel(8)
- Cordova(8)
- Linux(7)
- Next.js(6)
- Apache(5)
- Shopify(4)
- REST API(4)
- Node.js(4)
- Smarty(3)
- Git(3)
- JSON(3)
- その他プログラミング(3)
- Google Apps API(3)
- Bootstrap(3)
- 環境構築・システム(3)
- TypeScript(2)
- EJS(2)
- RMS(2)
- Docker(2)
- Instagram API(2)
- Excel VBA(2)
- SVG(1)
- Dart(1)
- ECカートASP(1)
- Markdown(1)
- AMP(1)
- Nginx(1)
- XML(1)
- shellscript(1)
- Ruby(1)
- MySQL(1)