2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.js完全ガイド初心者向け。今すぐ試せるコード付き

Posted at

1. Next.jsとは

Next.jsは、Reactベースのフレームワークで、高速で効率的なウェブアプリケーション開発を可能にします。

// Next.jsの基本的な構造
my-app/
  ├── pages/
     └── index.js
  ├── public/
  ├── styles/
  └── package.json

この構造が、Next.jsプロジェクトの基本となります。

2. Next.jsの特徴

Next.jsには以下のような特徴があります:

  • サーバーサイドレンダリング(SSR)
  • 静的サイト生成(SSG)
  • ファイルベースのルーティング
  • APIルート
// pages/index.js (SSRの例)
export async function getServerSideProps() {
  const res = await fetch('https://api.example.com/data')
  const data = await res.json()
  return { props: { data } }
}

export default function Home({ data }) {
  return <div>{data.title}</div>
}

このコードは、サーバーサイドでデータをフェッチし、それをページコンポーネントに渡す例です。

3. 開発環境のセットアップ

Next.jsプロジェクトを始めるには、以下のコマンドを実行します:

npx create-next-app@latest my-blog
cd my-blog
npm run dev

これにより、新しいNext.jsプロジェクトが作成され、開発サーバーが起動します。

4. ページの作成

Next.jsでは、pagesディレクトリ内のファイルが自動的にルートになります。

// pages/index.js
export default function Home() {
  return <h1>ようこそ、Next.jsブログへ!</h1>
}

このコードで、トップページが作成されます。

5. ルーティング

Next.jsは、ファイルベースのルーティングを採用しています。

// pages/posts/[id].js
import { useRouter } from 'next/router'

export default function Post() {
  const router = useRouter()
  const { id } = router.query

  return <p>ポストID: {id}</p>
}

この例では、動的ルーティングを使用して、URLパラメータを取得しています。

6. レイアウトの作成

共通のレイアウトを作成することで、コードの再利用性が高まります。

// components/Layout.js
export default function Layout({ children }) {
  return (
    <div>
      <header>ヘッダー</header>
      <main>{children}</main>
      <footer>フッター</footer>
    </div>
  )
}

// pages/_app.js
import Layout from '../components/Layout'

function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  )
}

export default MyApp

この設定により、全てのページに共通のレイアウトが適用されます。

7. スタイリング

Next.jsは、CSSモジュールをサポートしています。

// styles/Home.module.css
.title {
  color: blue;
  font-size: 24px;
}

// pages/index.js
import styles from '../styles/Home.module.css'

export default function Home() {
  return <h1 className={styles.title}>スタイリングの例</h1>
}

このように、コンポーネント固有のスタイルを簡単に適用できます。

8. 画像の最適化

Next.jsのImageコンポーネントを使用すると、自動的に画像が最適化されます。

import Image from 'next/image'

export default function Avatar() {
  return <Image src="/avatar.png" alt="アバター" width={50} height={50} />
}

このコードは、画像の遅延読み込みや適切なサイズ変更を自動的に行います。

9. APIルート

Next.jsでは、サーバーレスAPIを簡単に作成できます。

// pages/api/hello.js
export default function handler(req, res) {
  res.status(200).json({ message: 'こんにちは!' })
}

このAPIは/api/helloでアクセス可能になります。

10. データフェッチング

Next.jsには、データフェッチングのための特別な関数があります。

// pages/index.js
export async function getStaticProps() {
  const res = await fetch('https://api.example.com/posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
  }
}

export default function Home({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

この例では、ビルド時にデータをフェッチし、ページコンポーネントにpropsとして渡しています。

11. 動的ルーティング

動的ルーティングを使用すると、パラメータに基づいてページを生成できます。

// pages/posts/[id].js
export async function getStaticPaths() {
  const res = await fetch('https://api.example.com/posts')
  const posts = await res.json()

  const paths = posts.map((post) => ({
    params: { id: post.id.toString() },
  }))

  return { paths, fallback: false }
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://api.example.com/posts/${params.id}`)
  const post = await res.json()

  return { props: { post } }
}

export default function Post({ post }) {
  return <h1>{post.title}</h1>
}

この例では、全ての可能なパスを生成し、各パスに対応するデータをフェッチしています。

12. SEO対策

Next.jsでは、next/headを使用してメタタグを簡単に設定できます。

import Head from 'next/head'

export default function Page() {
  return (
    <>
      <Head>
        <title>ページタイトル</title>
        <meta name="description" content="ページの説明" />
      </Head>
      <h1>ページコンテンツ</h1>
    </>
  )
}

これにより、各ページに適切なメタ情報を設定し、SEO対策を行うことができます。

13. パフォーマンス最適化

Next.jsには、パフォーマンス最適化のための機能が多数あります。

import dynamic from 'next/dynamic'

const DynamicComponent = dynamic(() => import('../components/heavy-component'))

export default function Home() {
  return (
    <div>
      <h1>ホーム</h1>
      <DynamicComponent />
    </div>
  )
}

この例では、動的インポートを使用して、必要な時にのみコンポーネントを読み込んでいます。

14. 認証の実装

Next.jsでの認証実装は、通常、APIルートとクライアントサイドの状態管理を組み合わせて行います。

// pages/api/login.js
import { sign } from 'jsonwebtoken'

export default function handler(req, res) {
  const { username, password } = req.body

  if (username === 'admin' && password === 'password') {
    const token = sign({ username }, process.env.JWT_SECRET)
    res.status(200).json({ token })
  } else {
    res.status(401).json({ message: '認証失敗' })
  }
}

// pages/login.js
import { useState } from 'react'
import { useRouter } from 'next/router'

export default function Login() {
  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')
  const router = useRouter()

  const handleSubmit = async (e) => {
    e.preventDefault()
    const res = await fetch('/api/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username, password }),
    })
    if (res.ok) {
      const { token } = await res.json()
      localStorage.setItem('token', token)
      router.push('/dashboard')
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={username}
        onChange={(e) => setUsername(e.target.value)}
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
      />
      <button type="submit">ログイン</button>
    </form>
  )
}

この例では、簡単なログイン機能を実装しています。実際のアプリケーションでは、より堅牢な認証システムが必要です。

15. テスト

Next.jsアプリケーションのテストには、Jest和Reactテスティングライブラリを使用できます。

// __tests__/index.test.js
import { render, screen } from '@testing-library/react'
import Home from '../pages/index'

describe('Home', () => {
  it('renders a heading', () => {
    render(<Home />)

    const heading = screen.getByRole('heading', {
      name: /welcome to next\.js!/i,
    })

    expect(heading).toBeInTheDocument()
  })
})

このテストは、ホームページに特定の見出しが表示されることを確認します。

16. デプロイ

Next.jsアプリケーションは、Vercelに簡単にデプロイできます。

npm install -g vercel
vercel

これらのコマンドを実行すると、アプリケーションがVercelにデプロイされます。

17. 国際化対応

Next.jsは、組み込みの国際化サポートを提供しています。

// next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'ja'],
    defaultLocale: 'en',
  },
}

// pages/index.js
import { useRouter } from 'next/router'

export default function Home() {
  const { locale } = useRouter()
  return <h1>{locale === 'en' ? 'Welcome' : 'ようこそ'}</h1>
}

この設定により、//jaの両方のルートが生成されます。

18. PWA対応

Next.jsアプリケーションをPWA(Progressive Web App)にするには、next-pwaパッケージを使用します。

// next.config.js
const withPWA = require('next-pwa')

module.exports = withPWA({
  pwa: {
    dest: 'public',
  },
})

この設定により、アプリケーションがオフラインでも動作するようになります。

19. TypeScriptの導入

Next.jsはTypeScriptを標準でサポートしています。

// pages/index.tsx
import { GetStaticProps, NextPage } from 'next'

interface Props {
  title: string
}

const Home: NextPage<Props> = ({ title }) => {
  return <h1>{title}</h1>
}

export const getStaticProps: GetStaticProps = async () => {
  return { props: { title: 'Welcome to Next.js!' } }
}

export default Home

このコードは、TypeScriptを使用してページコンポーネントとデータフェッチング関数を定義しています。

20. 実践的なブログ作成例

最後に、これまでの知識を活用して、簡単なブログアプリケーションを作成してみましょう。

// pages/index.js
import Link from 'next/link'

export default function Home({ posts }) {
  return (
    <div>
      <h1>ブログ記事一覧</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>
            <Link href={`/posts/${post.id}`}>
              <a>{post.title}</a>
            </Link>
          </li>
        ))}
      </ul>
    </div>
  )
}

export async function getStaticProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const posts = await res.json()

  return {
    props: {
      posts: posts.slice(0, 5),
    },
  }
}

// pages/posts/[id].js
import { useRouter } from 'next/router'

export default function Post({ post }) {
  const router = useRouter()

  if (router.isFallback) {
    return <div>Loading...</div>
  }

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </div>
  )
}

export async function getStaticPaths() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const posts = await res.json()

  const paths = posts.slice(0, 5).map((post) => ({
    params: { id: post.id.toString() },
  }))

  return { paths, fallback: true }
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`)
  const post = await res.json()

  return { props: { post } }
}

この例では、外部APIからブログ記事のデータを取得し、トップページに表示しています。各記事にはリンクが設定されており、クリックすると詳細ページに遷移します。詳細ページでは、記事の全文を表示しています。

以上が、Next.jsを使用した実践的なブログアプリケーションの基本的な実装例です。この基礎をもとに、さら

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?