← Назад к вопросам

Как работал старый Routing в Next?

2.0 Middle🔥 133 комментариев
#JavaScript Core

Комментарии (3)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Старый Pages Router в Next.js: как он работал

Next.js раньше использовал Pages Router (до версии 13), который основывался на file-system routing. Хотя это была отличная система, в Next.js 13+ её заменили на более мощный App Router. Но понимание Pages Router остаётся важным для legacy проектов и собеседований.

File-system Routing

Pages Router работал по простому принципу: структура файлов автоматически создавала роуты.

pages/
  index.js           -> /
  about.js           -> /about
  products.js        -> /products
  products/
    [id].js          -> /products/:id (динамический роут)
    [...slug].js     -> /products/* (catch-all роут)
  api/
    users.js         -> /api/users (API endpoint)
    users/[id].js    -> /api/users/:id

Базовая страница в Pages Router

// pages/index.js (главная страница)
export default function Home() {
  return <h1>Добро пожаловать!</h1>;
}

// pages/about.js (страница /about)
export default function About() {
  return <h1>О нас</h1>;
}

Динамические роуты

Квадратные скобки создавали динамические параметры:

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

export default function Post() {
  const router = useRouter();
  const { id } = router.query; // Получить параметр из URL

  return <h1>Post {id}</h1>;
}

// Возможные URL:
// /posts/1
// /posts/hello
// /posts/123-my-post

Catch-all роуты

Три точки [...param] ловили все оставшиеся сегменты:

// pages/docs/[...slug].js
import { useRouter } from 'next/router';

export default function Docs() {
  const router = useRouter();
  const { slug } = router.query; // массив сегментов

  return <h1>Docs: {slug?.join(' / ')}</h1>;
}

// /docs/getting-started        -> slug = ['getting-started']
// /docs/api/users              -> slug = ['api', 'users']
// /docs/guide/setup/steps       -> slug = ['guide', 'setup', 'steps']

getStaticProps и getServerSideProps

Pages Router использовал эти функции для генерации страниц:

// pages/posts/[id].js

// Static Generation (SSG)
export async function getStaticProps({ params }) {
  const post = await fetchPost(params.id);
  
  return {
    props: { post },
    revalidate: 60, // ISR: перегенерировать каждые 60 секунд
  };
}

// Нужно указать какие роуты pre-render
export async function getStaticPaths() {
  return {
    paths: [
      { params: { id: '1' } },
      { params: { id: '2' } },
    ],
    fallback: 'blocking', // или false, или true
  };
}

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

Server-Side Rendering:

// pages/user-profile.js
export async function getServerSideProps(context) {
  const { req, res } = context;

  // Выполняется на каждом запросе (медленнее, но свежие данные)
  const user = await fetchUser(req.headers.cookie);

  if (!user) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }

  return {
    props: { user },
  };
}

export default function Profile({ user }) {
  return <h1>{user.name}</h1>;
}

API Routes

API создавались в папке pages/api:

// pages/api/users.js
export default function handler(req, res) {
  if (req.method === 'GET') {
    res.status(200).json({ users: [] });
  } else if (req.method === 'POST') {
    res.status(201).json({ created: true });
  } else {
    res.status(405).json({ error: 'Method Not Allowed' });
  }
}

// pages/api/users/[id].js
export default function handler(req, res) {
  const { id } = req.query;

  if (req.method === 'GET') {
    res.status(200).json({ id, user: 'John' });
  }
}

Навигация в Pages Router

import Link from 'next/link';
import { useRouter } from 'next/router';

export default function Navigation() {
  const router = useRouter();

  return (
    <>
      {/* Link компонент для навигации */}
      <Link href="/about">
        <a>О нас</a>
      </Link>

      {/* Программная навигация */}
      <button onClick={() => router.push('/dashboard')}>
        Перейти в панель
      </button>

      {/* Замена в истории вместо push */}
      <button onClick={() => router.replace('/home')}>
        Заменить страницу
      </button>
    </>
  );
}

Middleware (Pages Router)

Простое middleware выполнялось на каждом запросе:

// middleware.js (в корне проекта)
import { NextResponse } from 'next/server';

export function middleware(request) {
  // Редирект неавторизованных пользователей
  if (!request.cookies.get('auth')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ['/dashboard/:path*'], // Применить только к /dashboard
};

Сравнение Pages Router и App Router

Pages Router (старый)          App Router (новый)
====================================
pages/                          app/
Dynamic: [id].js                Dynamic: [id]/page.js
API Routes: pages/api/          API Routes: app/api/ (route.js)
getStaticProps                  generateStaticParams
getServerSideProps              нет прямого аналога
useRouter                        useRouter (из next/navigation)
Link с <a>                      Link без <a> тега

Пример: полная старая структура

// pages/index.js
export default function Home() {
  return <h1>Главная</h1>;
}

// pages/products/[id].js
export async function getStaticProps({ params }) {
  const product = await fetch(`/api/products/${params.id}`);
  return { props: { product }, revalidate: 60 };
}

export async function getStaticPaths() {
  return {
    paths: [{ params: { id: '1' } }],
    fallback: 'blocking',
  };
}

export default function Product({ product }) {
  return <h1>{product.name}</h1>;
}

// pages/api/products/[id].js
export default function handler(req, res) {
  const { id } = req.query;
  res.json({ id, name: 'Product ' + id });
}

Почему заменили на App Router

  1. Server Components — лучшая производительность
  2. Layouts — вложенные слои без повторов кода
  3. Более гибкий routing — не привязан к файловой структуре
  4. Единая система — API и страницы в одной папке
  5. Лучше для Large Scale приложений

Pages Router отличался простотой и intuitiveness, но App Router более мощный для больших проектов. На собеседованиях могут спросить, как работал Pages Router, чтобы оценить твой опыт с Next.js эволюцией.