Next.js 13.4の発表でApp Routerが正式にリリースされ、アプリケーションの構築をより効果的にするための新機能が多数追加されました。中でも「App Router」、「Server Components」、「Nested Layouts」は、現代的なウェブアプリケーションの開発を支える重要な機能です。この記事では、これらの機能を具体的に説明し、実際のコード例を交えながら使い方を解説します。
#1. Next.jsのプロジェクトのセットアップ
まずはNext.jsのプロジェクトを新たに作成し、基本的なセットアップを行います。
プロジェクトの作成
以下のコマンドを実行して、新しいNext.jsプロジェクトを作成します。
npx create-next-app@latest my-nextjs-app cd my-nextjs-app
TypeScriptの設定(オプション)
TypeScriptを使用する場合は、以下のコマンドでTypeScriptをインストールし、設定ファイルを生成します。
npm install --save-dev typescript @types/react @types/node npx tsc --init
これでtsconfig.json
が生成され、TypeScriptが利用可能になります。
#2. App Routerの概要と基本的な使い方
App Routerとは?
App Routerは、app
ディレクトリを使用してページやレイアウトを管理する新しいルーティングシステムです。従来の pages
ディレクトリベースのルーティングに代わって、より柔軟で強力なルーティングが可能になります。
プロジェクト構造
以下のディレクトリ構造を用意し、基本的なルーティングを設定します。
my-nextjs-app/ └── app/ ├── layout.tsx ├── page.tsx ├── about/ │ └── page.tsx ├── contact/ │ └── page.tsx └── blog/ ├── layout.tsx ├── page.tsx └── [slug]/ └── page.tsx
app/layout.tsx
全ページで共通のレイアウト(ヘッダーやフッターなど)を設定します。
// app/layout.tsx import { ReactNode } from 'react'; const Layout = ({ children }: { children: ReactNode }) => { return ( <div> <header> <nav> <a href="/">Home</a> <a href="/about">About</a> <a href="/contact">Contact</a> <a href="/blog">Blog</a> </nav> </header> <main>{children}</main> <footer> <p>© 2024 My Next.js App</p> </footer> </div> ); }; export default Layout;
app/page.tsx
ホームページのコンテンツを定義します。
// app/page.tsx const HomePage = () => { return <h1>Home Page</h1>; }; export default HomePage;
app/about/page.tsx
Aboutページのコンテンツを定義します。
// app/about/page.tsx const AboutPage = () => { return <h1>About Page</h1>; }; export default AboutPage;
app/contact/page.tsx
Contactページのコンテンツを定義します。
// app/contact/page.tsx const ContactPage = () => { return <h1>Contact Page</h1>; }; export default ContactPage;
app/blog/layout.tsx
Blogセクションのレイアウトを定義します。
// app/blog/layout.tsx import { ReactNode } from 'react'; const BlogLayout = ({ children }: { children: ReactNode }) => { return ( <div> <aside> <h2>Blog Sidebar</h2> <ul> <li><a href="/blog">Blog Home</a></li> {/* 他のサイドバーリンク */} </ul> </aside> <main>{children}</main> </div> ); }; export default BlogLayout;
app/blog/page.tsx
Blogのホームページのコンテンツを定義します。
// app/blog/page.tsx const BlogPage = () => { return <h1>Blog Home Page</h1>; }; export default BlogPage;
app/blog/[slug]/page.tsx
動的なブログポストページを定義します。
// app/blog/[slug]/page.tsx import { useRouter } from 'next/router'; const BlogPost = () => { const router = useRouter(); const { slug } = router.query; return <h1>Blog Post: {slug}</h1>; }; export default BlogPost;
#3. Server Componentsの概要と活用方法
Server Componentsとは?
Server Componentsは、サーバーサイドでのみレンダリングされるコンポーネントです。これにより、クライアントサイドのJavaScriptバンドルサイズを削減し、パフォーマンスを向上させることができます。
Server Componentsの作成と利用
以下は、サーバーサイドでデータを取得して表示するServer Componentの例です。
// app/components/ServerComponent.tsx const ServerComponent = async () => { const res = await fetch('https://jsonplaceholder.typicode.com/posts/1'); const post = await res.json(); return ( <div> <h2>Server Component</h2> <p>Title: {post.title}</p> <p>Body: {post.body}</p> </div> ); }; export default ServerComponent;
ServerComponent
の利用方法
Server Componentは通常のReactコンポーネントのように利用します。
// app/page.tsx import ServerComponent from './components/ServerComponent'; const HomePage = () => { return ( <div> <h1>Home Page</h1> <ServerComponent /> </div> ); }; export default HomePage;
Server Componentsのメリット
- パフォーマンスの向上: サーバーサイドでデータ取得とレンダリングを行うため、クライアントサイドのJavaScriptバンドルサイズを削減できます。
- セキュリティの向上: サーバーサイドで機密情報を処理できるため、クライアント側に機密情報が露出しません。
#4. Nested Layoutsの概要と設定方法
Nested Layoutsとは?
Nested Layoutsは、複数のレイアウトを階層的に構築し、ページの構造を整理するための機能です。これにより、共通のレイアウト要素を効率的に再利用できます。
プロジェクト構造
以下のようなディレクトリ構造で、ネストされたレイアウトを設定します。
my-nextjs-app/ └── app/ ├── layout.tsx ├── page.tsx ├── blog/ │ ├── layout.tsx │ ├── page.tsx │ └── [slug]/ │ └── page.tsx └── about/ └── page.tsx
app/blog/layout.tsx
Blogセクション専用のレイアウトを設定します。
// app/blog/layout.tsx import { ReactNode } from 'react'; const BlogLayout = ({ children }: { children: ReactNode }) => { return ( <div> <aside> <h2>Blog Sidebar</h2> <ul> <li><a href="/blog">Blog Home</a></li> <li><a href="/blog/2024">2024 Blog Posts</a></li> </ul> </aside> <main>{children}</main> </div> ); }; export default BlogLayout;
app/blog/page.tsx
Blogのホームページのコンテンツを定義します。
// app/blog/page.tsx const BlogPage = () => { return <h1>Blog Home Page</h1>; }; export default BlogPage;
app/blog/[slug]/page.tsx
動的なブログポストページを定義します。
// app/blog/[slug]/page.tsx import { useRouter } from 'next/router'; const BlogPost = () => { const router = useRouter(); const { slug } = router.query; return <h1>Blog Post: {slug}</h1>; }; export default BlogPost;
Nested Layoutsのメリット
- レイアウトの再利用: 異なるセクションごとに異なるレイアウトを設定できるため、共通のレイアウト要素を効率的に再利用できます。
- 構造の整理: ページやレイアウトを階層的に構築することで、アプリケーションの構造を整理しやすくなります。
#5. 実践的なプロジェクト例
プロジェクトの概要
以下の実践的なプロジェクト例では、ブログアプリケーションの基本的な構造を示します。App Router
、Server Components
、Nested Layouts
を活用して、動的なブログポストを表示するシンプルなアプリケーションを作成します。
プロジェクトのコード
// app/layout.tsx import { ReactNode } from 'react'; const MainLayout = ({ children }: { children: ReactNode }) => { return ( <div> <header> <nav> <a href="/">Home</a> <a href="/about">About</a> <a href="/contact">Contact</a> <a href="/blog">Blog</a> </nav> </header> <main>{children}</main> <footer> <p>© 2024 My Blog App</p> </footer> </div> ); }; export default MainLayout;
// app/page.tsx const HomePage = () => { return <h1>Welcome to the Blog Home Page</h1>; }; export default HomePage;
// app/about/page.tsx const AboutPage = () => { return <h1>About Us</h1>; }; export default AboutPage;
// app/contact/page.tsx const ContactPage = () => { return <h1>Contact Us</h1>; }; export default ContactPage;
// app/blog/layout.tsx import { ReactNode } from 'react'; const BlogLayout = ({ children }: { children: ReactNode }) => { return ( <div> <aside> <h2>Blog Sidebar</h2> <ul> <li><a href="/blog">Blog Home</a></li> <li><a href="/blog/2024">2024 Posts</a></li> </ul> </aside> <main>{children}</main> </div> ); }; export default BlogLayout;
// app/blog/page.tsx const BlogPage = () => { return <h1>Blog Home Page</h1>; }; export default BlogPage;
// app/blog/[slug]/page.tsx import { useRouter } from 'next/router'; const BlogPost = () => { const router = useRouter(); const { slug } = router.query; return <h1>Blog Post: {slug}</h1>; }; export default BlogPost;
// app/components/ServerComponent.tsx const ServerComponent = async () => { const res = await fetch('https://jsonplaceholder.typicode.com/posts/1'); const post = await res.json(); return ( <div> <h2>Server Component</h2> <p>Title: {post.title}</p> <p>Body: {post.body}</p> </div> ); }; export default ServerComponent;
// app/page.tsx import ServerComponent from './components/ServerComponent'; const HomePage = () => { return ( <div> <h1>Welcome to the Blog Home Page</h1> <ServerComponent /> </div> ); }; export default HomePage;
このプロジェクトの特徴
- App Routerを使ってページとレイアウトを管理しています。
- Server Componentsを使ってサーバーサイドでデータを取得し表示しています。
- Nested Layoutsを使って、Blogセクションに専用のレイアウトを設定しています。
#6. まとめ
Next.jsのApp Router、Server Components、Nested Layoutsは、現代のウェブアプリケーションの開発において非常に強力なツールです。これらの機能を使いこなすことで、より効率的でスケーラブルなアプリケーションを構築することができます。
主なポイント
- App Router: app ディレクトリを使用して、ページやレイアウトの管理を行う新しいルーティングシステムです。
- Server Components: サーバーサイドでのみレンダリングされるコンポーネントで、パフォーマンスの向上やセキュリティの強化が可能です。
- Nested Layouts: 複数のレイアウトを階層的に構築し、ページの構造を整理するための機能です。
これらの機能を適切に活用し、次のプロジェクトで新しいNext.jsの機能を試してみてください。興味があれば、公式ドキュメントも参考にしてさらなる学びを深めていきましょう。