Next.js: гайд для новичков

Разбираемся с фреймворком, который используют в Netflix, Twitch и TikTok.

88 просмотров
Next js гайд для новичков - вместе

Next js гайд для новичков - вместе

В этой статье я расскажу, что такое Next.js, как он помогает быстрее и проще создавать приложения, а также почему он идеально подходит для новичков. Я также объясню, как Next.js улучшает производительность твоего приложения и помогает сделать его более заметным в поисковиках.

⚠️ Важное предупреждение! этой статье мы будем в основном говорить про подход App Router в Next.js, так как он является рекомендуемым методом для новых проектов начиная с версии 13 и выше.

Почему? Потому что:

  • Он предоставляет больше гибкости и мощные возможности, такие как Server Components и Nested Layouts.
  • App Router активно развивается и является будущим маршрутизации в Next.js.

Из этой статьи вы узнаете:

Что такое Next.js

Next.js — инструменте для создания веб-сайтов и приложений, который был разработан компанией Vercel (раньше называлась Zeit) и выпущен в 2016 году как открытый проект. С тех пор Next.js стал одним из самых популярных инструментов среди разработчиков благодаря своей простоте, удобству и множеству полезных функций. Вот почему я считаю его таким отличным выбором для создания современных сайтов и приложений:

1. Простота и удобство разработки

С помощью Next.js можно быстро начать разработку, не тратя много времени на настройки. Он сам решает многие технические моменты, такие как маршрутизация, стилизация и сборка проекта. Это позволяет сосредоточиться на самом контенте и функционале, не думая о том, как настроить сервер или маршруты для страниц.

2. Серверная отрисовка (SSR) и статическая генерация (SSG)

Next.js дает возможность выбирать, как создавать страницы:

  • Серверная отрисовка (SSR): чтобы страницы генерировались на сервере каждый раз, когда пользователь заходит на сайт. Это ускоряет загрузку страниц и помогает с поисковой оптимизацией.
  • Статическая генерация (SSG): дает заранее создавать страницы во время сборки, чтобы они загружались быстрее. Это особенно полезно для сайтов с небольшими или нечасто меняющимися данными.

3. Маршрутизация через файловую систему

Next.js использует файловую систему для автоматической маршрутизации. Это означает, что в папке app каждая папка и файл могут становиться маршрутом (страницей) на сайте. Например, если я создам папку app/about, а внутри этой папки файл page.jsx, эта страница будет доступна по адресу /about. Такой подход упрощает организацию проекта и позволяет легко добавлять новые страницы без дополнительных настроек.

4. Оптимизация производительности "из коробки"

Next.js автоматически заботится о производительности сайта. Он минимизирует JavaScript, разделяет код и загружает только необходимые части страницы, когда это нужно. Это помогает пользователям быстро загружать страницы, даже если у них медленный интернет.

5. Полная совместимость с React

Так как Next.js построен на React, мы можем использовать все преимущества этого инструмента: компоненты, хуки и другие мощные фичи. Это значит, что мы можем создавать удобные, модульные интерфейсы, а также использовать React для работы с данными и состоянием на странице.

6. Гибкость и расширяемость

Next.js предоставляет массу полезных возможностей, которые позволяют нам создавать как простые, так и сложные приложения. Мы можем использовать API маршруты для работы с серверной логикой, интегрировать TypeScript для лучшей проверки кода и стилизовать сайт любым удобным для нас способом. Это делает Next.js гибким инструментом, который подойдёт для проектов разного масштаба.

На момент написания статьи актуальная версия Next.js — 15.0.4, которая вышла в октябре 2024 года.

Маршрутизация в Next.js

В Next.js маршрутизация основана на файловой системе. Это означает, что структура папок и файлов в проекте напрямую определяет URL-адреса на сайте. В Next.js доступно два способа маршрутизации: Pages Router и App Router.

1. Pages Router

Pages Router используется в папке pages/.

Как это работает:

  • Каждый файл в папке pages/ становится страницей.
  • Например, файл pages/about.js будет доступен по адресу /about.

bash

/pages
  ├── api             // API маршруты
  │   ├── hello.js     // URL: /api/hello
  │   └── users.js     // URL: /api/users
  ├── blog
  │   ├── [id].js      // URL: blog/:id (динамический маршрут)
  │   └── index.js     // URL: https://mywebsite.ru/blog
  ├── about.js         // URL: https://mywebsite.ru/about
  ├── contact.js       // URL: https://mywebsite.ru/contact
  ├── index.js         // URL: https://mywebsite.ru/
  └── _app.js          // Главный файл для общего оформления
  └── _document.js     // Для настройки HTML-документа

Когда использовать Pages Router:

  • Если вы работаете с классическим подходом маршрутизации.
  • Если проект требует стабильности и не использует современные функции React.

2. App Router

App Router работает с папкой app/ и стал доступен начиная с Next.js 13. Это современный подход, который позволяет использовать новые функции, такие как серверные компоненты, Layouts и Partial Prerendering (PPR). Рекомендуется использовать его

Как это работает:

  • Каждая папка и файл в app/ становятся маршрутом.
  • Например, папка app/about с файлом page.js будет доступна по адресу /about.

bash

/app
  ├── about
  │   └── page.js      // URL: https://mywebsite.ru/about
  ├── blog
  │   ├── [id]
  │   │   └── page.js  // URL: https://mywebsite.ru/blog/:id
  ├── layout.js        // Общий Layout для всех страниц
  └── page.js          // URL: https://mywebsite.ru/

Когда использовать App Router:

  • Если вы хотите использовать серверные компоненты и другие современные функции.
  • Если работаете над новым проектом.

Server Components (Серверные компоненты)

Серверные компоненты в Next.js позволяют выполнять рендеринг на сервере и отправлять готовый HTML на клиент, минимизируя размер JavaScript, который загружается в браузер. Они особенно полезны для улучшения производительности и SEO.

Как настроить и использовать Server Components

  1. Использование App Router Серверные компоненты доступны только с маршрутизацией через папку app. Убедитесь, что вы используете App Router.
  2. Создание серверных компонентов Файлы серверных компонентов по умолчанию рендерятся на сервере. Просто используйте расширение .jsx или .tsx.
  3. Пример структуры файлов:

bash

/app
  ├── page.jsx          // Главная страница (Серверный компонент)
  ├── layout.jsx        // Общий Layout (Серверный компонент)
  ├── components
  │   ├── ServerComponent.jsx // Пример серверного компонента
  │   └── ClientComponent.jsx // Пример клиентского компонента
  1. Создание серверного компонента: Серверные компоненты можно экспортировать как обычные функции. Они могут использовать серверные API и не включают JavaScript на клиенте.

javascript

// app/components/ServerComponent.jsx

export default async function ServerComponent() {
 const data = await fetch("https://api.example.com/data").then((res) =>
   res.json()
 );

 return (
   <div>
     <h1>Данные с сервера:</h1>
     <pre>{JSON.stringify(data, null, 2)}</pre>
   </div>
 );
}
  1. Создание клиентского компонента: Если компонент должен работать с интерактивностью (например, с состояниями через React useState), используйте директиву "use client":

javascript

// app/components/ClientComponent.jsx
"use client";

import { useState } from "react";

export default function ClientComponent() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>Счетчик:</h1>
      <button onClick={() => setCount(count + 1)}>Увеличить</button>
      <p>Текущее значение: {count}
    </div>
  );
}
  1. Использование серверных и клиентских компонентов вместе: Вы можете использовать серверные компоненты как "обёртку" для клиентских:

javascript

// app/page.jsx

import ServerComponent from "./components/ServerComponent";
import ClientComponent from "./components/ClientComponent";

export default function Page() {
 return (
   <div>
     <ServerComponent />
     <ClientComponent />
   </div>
 );
}
  1. Асинхронные серверные компоненты: Серверные компоненты могут быть асинхронными, что позволяет использовать fetch и другие серверные API без необходимости дополнительного клиента:

javascript

// app/page.jsx

export default async function Page() {
 const res = await fetch("https://api.example.com/data");
 const data = await res.json();

 return (
   <div>
     <h1>Асинхронный серверный компонент</h1>
     <pre>{JSON.stringify(data, null, 2)}</pre>
   </div>
 );
}

Если вы попробуете использовать async function в компоненте с "use client", React на вас обидится и скажет: "Эй, я тут на клиенте, зачем мне серверные дела?".

Вот что нужно помнить:

  • Компоненты с "use client" работают только в браузере, а браузер не умеет ждать асинхронные функции в рендере. Это как пытаться сделать кофе в чайнике — результат может быть, но явно не тот, что вы ожидали.

Пример ошибки:

javascript

"use client";

export default async function Oops() {
 // Браузер посмотрит на это и скажет: "Нет, дружище".
 return <div>Привет, мир!</div>;
}

}

Что делать?

Если вам срочно нужно что-то "асинхронное", сделайте это заранее. Например, используйте эффект (useEffect) для асинхронной логики:

javascript

"use client";

import { useEffect, useState } from "react";

export default function NoOops() {
 const [data, setData] = useState(null);

 useEffect(() => {
   async function fetchData() {
     const response = await fetch("/api/data");
     const json = await response.json();
     setData(json);
   }
   fetchData();
 }, []);

 return <div>{data ? JSON.stringify(data) : "Загрузка..."}</div>;
}

Динамические маршруты в Next js

Динамические маршруты позволяют создавать страницы с динамически изменяемыми частями пути, основываясь на параметрах URL. Это помогает генерировать страницы на основе данных или переменных, например, для отображения информации о различных продуктах или блогах.

В Next.js динамические маршруты создаются с помощью файлов, которые содержат параметры в квадратных скобках, например:

bash

/app
└── /blog
    └── [slug]
          └── page.jsx

page.jsx – файл, который будет обрабатывать запросы с любыми значениями slug в URL. Например, если вы перейдете по адресу http://localhost:3000/blog/landing, то Next.js отобразит страницу из этого файла и передаст значение slug в компонент.

Внутри этого файла можно будет получать параметр slug из URL

javascript

export default async function BlogPost({ params }) {
const {slug} = await params;
  return <h1>Статья: {slug}</h1>;
}

Пример URL: /blog/hello-world → отображается "Статья: hello-world".

Работа с params

  • params доступен для получения переменных из маршрута.
  • Используйте generateStaticParams для предзагрузки данных.

Как подключить стили в Next js

В Next.js есть несколько способов добавления стилей в наше приложение. Вот основные методы, которые можно использовать для стилизации компонентов:

1. CSS Модули

CSS модули — это один из самых популярных способов стилизации в Next.js. Они позволяют создавать локальные стили для компонентов, что предотвращает конфликты имен классов.

Как использовать CSS Модули:

  • Создайте файл стилей с расширением .module.css (например, styles.module.css).
  • Импортируйте и используйте классы из этого файла в компонентах.

Пример:

  • Создайте файл стилей styles.module.css:

css

/* styles.module.css */
.container {
  padding: 20px;
  background-color: #f0f0f0;
  border-radius: 8px;
}

.title {
  font-size: 2rem;
  color: #333;
}

Импортируйте стили в компонент:

javascript

import styles from './styles.module.css';
export default  function Home() {
return (
    <div className={styles.container}>
      <h1 className={styles.title}>Hello, Next.js!</h1>
    </div>
  );
}

Примечания:

  • Классы в CSS модулях автоматически становятся уникальными, чтобы избежать конфликтов.
  • Для использования CSS-модулей файлы должны иметь суффикс .module.css.

2. Глобальные стили

Если вам нужно добавить глобальные стили, например, для всего приложения, их можно добавить через файл globals.css.

Как использовать глобальные стили:

  • Создайте файл /globals.css.
  • Импортируйте его в layout.js для применения ко всем страницам.

Пример:

Создайте файл styles/globals.css:

css

body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
  background-color: #fff;
}
.container {
  max-width: 1350px;
  padding: 0 10px;
  margin: 0 auto;
}

h1, h2, h3 {
  margin: 0;
  padding: 0;
}

Импортируйте файл globals.css в app.js:

javascript

import './globals.css';

export default function RootLayout({ children }) {
  return (
    <html lang="ru">
      <body>{children}</body>
    </html>
  );
}

Теперь эти стили будут применяться ко всем страницам вашего приложения.

Навигация перехода между страницами в Next js

Next.js предоставляет компонент Link, который является основным инструментом для перехода между страницами в приложении. Он обрабатывает оптимизацию маршрутов, кэширование, а также предотвращает полную перезагрузку страницы, что позволяет улучшить производительность.

javascript

import Link from 'next/link';

export default function Home() {
  return (
    <nav>
      <Link href="/about">О нас</Link>
      <Link href="/blog">Блог</Link>
    </nav>
  );
}

⚠️ Важное предупреждение! Используйте компонент Link для навигации между страницами в Next.js, а не обычный тег a, потому что:

  • Это предотвращает полную перезагрузку страницы, улучшая производительность.
  • Он предзагружает страницы, делая переходы быстрее.
  • Он оптимизирован для работы с серверной отрисовкой (SSR), что помогает в SEO.

Использование Link — это лучший и рекомендованный способ навигации в Next.js!

Получение данных в Next.js

Next.js предлагает несколько методов для получения данных, которые зависят от потребностей проекта:

1. Загрузка данных в серверных компонентах

Серверные компоненты позволяют загружать данные напрямую с сервера, используя fetch.

javascript

export default async function Page() {
  const res = await fetch('https://api.example.com/data', { cache: 'no-store' });
  const data = await res.json();
  return <div>{JSON.stringify(data)}</div>;
}
  • Здесь происходит асинхронный HTTP-запрос с использованием функции fetch. Он отправляет запрос на URL https://localhost:3000/api, для получения данных.

  • Параметр { cache: 'no-store' } указывает, что браузер не должен кэшировать этот запрос. Каждый раз при рендере компонента будет выполняться новый запрос, и данные будут получены заново.

2. SSR (Server-Side Rendering)

Загрузка данных на сервере при каждом запросе через getServerSideProps.

javascript

export async function getServerSideProps() {
  const res = await fetch('https://api.example.com/data');
  const data = await res.json();
  return { props: { data } };
}

Это функция, которая выполняется на сервере при каждом запросе к странице. Она позволяет загружать данные до рендеринга страницы, и эти данные передаются как свойства (props) в компонент страницы.

3. SSG (Static Site Generation)

Статическая генерация данных во время сборки с поддержкой ISR (Incremental Static Regeneration).

javascript

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/data',{ cache: 'force-cache' });
  const data = await res.json();
  return { props: { data }, revalidate: 60 }; // Обновление каждые 60 секунд
}
  • return { props: { data }, revalidate: 60 } — возвращает данные как пропсы для страницы. Также указано свойство revalidate: 60, что означает, что данные будут обновляться (перегенерироваться) каждые 60 секунд, даже если страница использует статическую генерацию. Это подходит для страниц, где данные могут часто изменяться.
  • В данном примере используется кэширование ответа с помощью опции { cache: 'force-cache' }, чтобы минимизировать количество запросов к серверу и уменьшить нагрузку. Убедитесь, что данные кэшируются должным образом, чтобы избежать чрезмерной нагрузки на сервер.

Такой подход позволяет эффективно работать с данными, которые обновляются через определённые интервалы, без необходимости постоянно выполнять запросы.

⚠️ Важное предупреждение! По умолчанию Next.js не кэширует данные, полученные с помощью fetch. Это значит, что каждый запрос к API может привести к новой генерации страницы и дополнительной нагрузке на сервер.

4. Загрузка данных в клиентских компонентах

Для интерактивных компонентов данные можно загружать через useEffect.

javascript

'use client';
import { useEffect, useState } from 'react';

export default function Page() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then((res) => res.json())
      .then(setData);
  }, []);

  return <div>{JSON.stringify(data)}</div>;
}

Обработка ошибок в Next js

В Next.js страницы обрабатываются автоматически, если файл находится в соответствующей директории app. Для страницы с ошибкой 404 нужно создать файл not-found.jsx в папке app вашего проекта.

javascript

export default function NotFound() {
  return <h1>Страница не найдена</h1>;
}

C использованием App Router, нужно создать файл not-found.jsx в директории app. Вот как должна выглядеть структура папок и файлов для этого:

bash

itvmeste/
├── app/
│   ├── not-found.jsx
│   ├── layout.jsx
│   ├── page.jsx
│   ├── some-folder/
│   │   ├── page.jsx
│   │   └── other-files.js
│   └── api/
│       └── route.js
├── public/
│   ├── images/
│   │   └── example.jpg
│   └── favicon.ico
├── styles/
│   ├── globals.css
│   └── other-styles.css
├── next.config.js
├── package.json
└── README.md

Оптимизация изображение

Компонент Image в Next.js предоставляет оптимизированный способ работы с изображениями. Он помогает улучшить производительность приложения, автоматизируя задачи, такие как адаптация размеров, lazy loading и форматирование.

Особенности компонента Image

  1. Оптимизация изображений:
    • Изображения автоматически ресайзятся в зависимости от устройства по
    • Поддерживаются современные форматы (например, WebP).
  2. Lazy Loading по умолчанию:
    • Изображения загружаются только тогда, когда становятся видимыми в viewport.
  3. Responsive и фиксированные размеры:
    • Вы можете указать как фиксированные размеры изображения, так и настроить его адаптацию под разные экраны.
  4. CDN и кэширование:
    • Next.js автоматически использует встроенный Image Optimization API, позволяя хранить обработанные изображения в кэше.

javascript

import Image from 'next/image';

export default function Home() {
  return (
    <Image 
      src="/images/example.jpg" // путь к изображению
      alt="Пример изображения" // описание для SEO
      width={800} // ширина обязательно 
      height={600} // высота обязательно
    />
  );
}

Загрузка изображений с внешнего ресурса

Если вы используете изображения, которые хранятся на стороннем сервере, нужно добавить их домен в файл next.config.js:

javascript

module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com', // ваш домен
        pathname: '/images/**', // путь к изображениям
      },
    ],
  },
};

Погнали, Next.js: создаём первый проект

Для того чтобы начать работу с Next.js, давайте сначала установим его.

  1. Убедитесь, что у вас установлен пакетный менеджер NPM или Yarn.
  2. Откройте терминал и перейдите в папку, в которой будет находиться проект. Для этого можно использовать команду cd
  3. Запустите команду ниже, которая установит последнюю версию Next.js и инициализирует новый проект.

javascript

npx create-next-app@latest
  1. Во время инициализации надо ответить на несколько вопросов, которые помогут настроить проект:
  2. Во время инициализации надо ответить на несколько вопросов, которые помогут настроить проект:
ВопросПереводЗначение по умолчанию
1 What is your project named?Имя проектаmy-app
2 Would you like to use TypeScript? No/YesВы хотите использовать TypeScript?Yes
3 Would you like to use ESLint? No/YesВы хотите использовать ESLint?Yes
4 Would you like to use Tailwind CSS? No/YesВы хотите использовать Tailwind CSS?No
5 Would you like to use src/ directory? No/YesВы хотите использовать папку src?Yes
6 Would you like to use App Router? (recommended)Хотели бы вы использовать App Router? (рекомендуется)Yes
7 Would you like to customize the import alias No/YesХотите ли вы настроить псевдоним для импортаYes
  1. Теперь вы можете запустить проект всего одной командой:

javascript

npm run dev

Поздравляем, ваш первый проект на Next.js готов и запущен!

Из чего состоит проект Next.js

Давайте посмотрим на структуру вашего проекта. Внутри проекта вы найдете несколько папок, каждая из которых имеет свою роль:

  • app — страницы приложения с навигацией через app
  • public — папка для хранения статических ресурсов;
  • src — дополнительная папка для исходников проекта.

bash

itvmeste/
├── app/                        # Главная папка для всех маршрутов и компонентов
│   ├── page.jsx                # Главная страница (главный маршрут)
│   ├── layout.jsx              # Общий макет для всего приложения
│   ├── error.jsx               # Глобальный обработчик ошибок
│   ├── not-found.jsx           # Страница 404 (обработчик отсутствующих маршрутов)
│   ├── api/                    # Папка для маршрутов API
│   │   ├── hello/              # Пример маршрута API
│   │   │   └── route.js        # Файл с логикой маршрута API
│   ├── about/                  # Пример дочернего маршрута
│   │   └── page.jsx            # Страница для маршрута "/about"
│   └── [dynamic]/              # Пример динамического маршрута
│       └── page.jsx            # Динамическая страница с параметром
├── public/                     # Папка для статических файлов (картинки, шрифты, иконки и т.д.)
│   ├── images/                 # Пример папки с изображениями
│   └── favicon.ico             # Фавиконка сайта
├── styles/                     # Папка для стилей
│   ├── globals.css             # Глобальные стили
│   └── other-styles.css        # Дополнительные стили
├── next.config.js              # Конфигурация Next.js
├── package.json                # Файл зависимостей и скриптов
└── README.md                   # Документация проекта

Как добавлять страницы в проект

В Next.js страницы создаются автоматически, если добавить файл в специальную папку app.

Пример создания простого шаблона:

javascript

// app/layout.jsx общий макет

import Header from './Header';
import Footer from './Footer';

export default async function RootLayout({ children }) {
  return (
    <>
      <Header />
      <main>{children}</main>
      <Footer />
    </>
  );
}

Подводим итоги

Подводя итоги, хочу отметить, что статья пытается дать общее представление о Next.js и его возможностях, но, возможно, не охватывает все нюансы и тонкости работы с этим фреймворком.

  • Основное внимание уделено современному подходу App Router, который является рекомендованным для новых проектов начиная с версии 13.
  • Рассмотрены важные аспекты, такие как серверные компоненты, динамические маршруты, стилизация и оптимизация производительности.
  • Однако для более глубокого понимания и работы с Next.js, стоит ознакомиться с дополнительными источниками и документацией. Или задайте вопрос chat gpt она вам поможет.

Статья может быть полезной для новичков, но она не является исчерпывающей и не охватывает все детали, которые могут встретиться в реальных проектах. Все же, надеюсь, что удалось передать основные идеи и помочь разобраться с основами Next.js.

Откройте мир IT-технологий и продвижения сайтов!
Откройте мир IT-технологий и продвижения сайтов!

Подписывайтесь на канал, чтобы быть в курсе всех новинок в сфере технологий и узнать секреты успешного продвижения сайтов. Практические советы, актуальные тренды и всё, что нужно для роста в digital-мире!

Подписаться