React Junior
208 subscribers
37 photos
462 links
Изучение React с нуля
Download Telegram
Next.js. Динамические роуты

Про динамические роуты мы уже знаем: можно создать файл pages/post/[id].tsx и он будет соответствовать множеству страниц /post/1, post/2, post/hello и т.д.

При этом в компоненте страницы можно узнать конкретный id, воспользовавшись хуком useRouter (в поле router.query.id).

Но это только один уровень вложенности, то есть страницу /post/react/23 так не опишешь. Если требуется вложенная структура, Next и это умеет.

Создаем страницу pages/post/[...id].tsx и получаем все возможные пути с любым уровнем вложенности.

При этом router.query.id будет не строкой, а массивом.

Если к этому набору урлов требуется добавить еще и просто /post (без id), название файла должно выглядеть так: pages/post/[[...id]].tsx.

#nextjs #серверныйроутинг #документация
👍3🔥1
Next.js. Api-роуты: примеры использования

Обычно не следует вызывать из апи-роута другой апи, но есть пара случаев, когда можно:

- вы хотите спрятать урл, к которому обращаетесь (поэтому запрос с клиента происходит на ваш апи /api/secret, а уже оттуда - на нужный https://company.com/secret-url)
- вы хотите использовать какие-то переменные окружения для формирования запроса

#nextjs #серверныйрендеринг #документация
👍1🔥1
Next.js. Динамические api-роуты

Для апи работают те же самые правила, что и для страниц.
Динамическую часть можно указать в квадратных скобках - api/post/[id].ts.
Если добавить три точки, будут отслеживаться все уровни вложенности - api/post/[...ids].ts.
Если при этом поставить двойные квадратные скобки, то будет опциональный вариант (будет совпадение если нет параметров вообще - api/post).
Доступ к динамическим параметрам можно получить из request.query.

#nextjs #серверныйрендеринг #документация
👍4
Next.js. Request и Response Helpers

В апи-роутах у нас приходит два параметра - объект запроса (req) и объект ответа (res).

req - это экземпляр класса http.IncomingMessage, а res - http.ServerResponse, но и тот, и другой имеют дополнительные плюшки (хелперы).

- req.cookies - все отправленные куки.
- req.query - параметры строки запроса.
- req.body - тело запроса, обработанное в соответствии с content-type.

- res.status(code) - метод для установки HTTP-кода ответа
- res.json(body) - отправить JSON
- res.send(body) - отправить HTTP-ответ (строчку, объект или Buffer)
- res.redirect([status, ], path) - для редиректа
- res.revalidate(urlPath) - ревалидация страницы по запросу.

Кроме того, из каждого роута в папке pages/api мы можем экспортировать объект конфигурации:

export const config = {
api: {

}
}


Подробнее можно посмотреть в документации:
https://nextjs.org/docs/api-routes/request-helpers
https://nextjs.org/docs/api-routes/response-helpers

#nextjs #серверныйрендеринг #документация
🔥3👍1
Next.js. Деплой проекта на Vercel

Vercel - это удобный хостинг для проектов на Next.js.

Развернуть проект очень-очень просто, даже у меня быстро получилось.
Просто регистрируемся на Vercel.com, создаем репозиторий с проектом (GitHub, GitLab, BitBucket) и импортируем его в Vercel.

Полностью поддерживаются все фичи Next.js (со всякими инкрементальными регенерациями), проект автоматически пересобирается при пуше в репозиторий. Интерфейс вроде понятный. Можно даже свой домен выбрать.

Мой учебный проект: https://furrycat.vercel.app/

Есть еще вариант задеплоить на Netlify или Heroku (но сейчас Heroku не регистрирует пользователей из России).
Подробнее тут: https://dzen.ru/a/YmuUb-ZF519-uyRP

#nextjs #серверныйрендеринг #инструменты
👍2🔥1
Next.js. Деплой на Node-сервере

Если нужно развернуть проект на обычном хостинге с поддержкой Node (не на специальном Vercel), потребуются две команды:

- next build - для сборки проекта
- next start - для запуска Next-сервера

#nextjs
👍4
Next.js. Подготовка к продакшену

Статья в документации (англ.): https://nextjs.org/docs/going-to-production

Вероятно, очень полезная статья о том, что нужно сделать перед тем, как отправлять проект в продакшн. Тут рассказывается о кешировании, обработке ошибок, оптимизации и уменьшении количества кода в клиентских бандлах.

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

#nextjs #серверныйрендеринг #документация #отложено #оптимизация
👍4
Next.js. Аутентификация

Статья в документации (англ.): https://nextjs.org/docs/authentication

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

Итак, есть два основных подхода:

1. Открывать страничку с состоянием загрузки (неаутентифицированную), а данные пользователя получать уже на клиенте и перерендеривать страницу после получения. Такую страничку можно статически генерировать, чтобы она открывалась очень быстро и можно было размещать еее на CDN.
2. Использовать SSR, то есть получать данные пользователя на сервере и возвращать страницу с контентом для уже известного пользователя. Используем для этого getServerSideProps. В этом случае не будет "моргания неавторизованного контента", а пользовать сразу получит то, что заслуживает (готовую страницу). Но если аутентификация занимает много времени, такой подход может принести проблемы.

Дальше посмотрим на примеры и готовые решения.

#nextjs #серверныйрендеринг #документация #аутентификация
👍3
Аутентификация в Next.js с использованием iron-session: Server Side Rendering

Меняем CSR на SSR: теперь запрос данных пользователя будет происходить на сервере при загрузке страницы.

Для этого добавляем нашей главной странице функцию getServerSideProps и уже внутри нее проверяем данные сессии, а объект user передаем на страницу в виде пропа.

Нам больше не нужно использовать хук useEffect для запроса данных, не нужен лоадер и роут /api/user.

Код страницы в репозитории: https://github.com/mohnatus/iron-session-ssr-demo/blob/master/pages/index.tsx

Демо: https://iron-session-ssr-demo.vercel.app/auth

#nextjs #примерыкода #документация #инструменты #аутентификация
👍3
Аутентификация в Next. Готовые решения

Мы мельком глянули на iron-session. Это довольно низкоуровневый инструмент для управления пользовательскими сессиями.

Документация Next.js предлагает еще несколько решений:

- next-auth - полноценная система аутентификации с кучей встроенных плюшек

а также:

- Auth0
- Clerk
- Firebase
- Magic
- Nhost
- Ory
- Supabase
- Supertokens
- Userbase

подробнее можно посмотреть по ссылочкам в документации: https://nextjs.org/docs/authentication#other-providers

#nextjs #документация #аутентификация #инструменты
👍2
Next.js. Тестирование: быстрый взгляд

Next подготовлен для работы с самыми популярными библиотеками тестирования: Cypress, Playwright, React Testing Library + Jest

Страница в документации со ссылками на примеры: https://nextjs.org/docs/testing

E2E тестирование пока не будем трогать, а вот на Unit поглядим.

Есть 3 способа начать использовать Jest + React Testing Library в приложении Next:

1) сразу создать приложение с нужными настройками и примерами:


npx create-next-app@latest --example with-jest with-jest-app


2) установить Jest в уже существующий проект:


npm install --save-dev jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom


Затем создать файл jest.config.js, а сам конфиг создать с помощью специальной функции nextJest. Передаем ей нужные параметры, а она сама добавит в конфиг много полезного.

3) и наконец полностью ручная настройка, которая выглядит очень страшно, не буду пока разбираться:
https://nextjs.org/docs/testing#setting-up-jest-with-babel

В целом тема тестирования у нас впереди, так что еще вернемся сюда.

#nextjs #документация #тестирование #отложено
🔥3👍1
Next.js. Продвинутые опции.

Переходим к более "продвинутым" страничкам документации. Тут будет кратенькое описание со ссылками. Некоторые пункты пропускаю, потому что не разбираюсь, а некоторые хочу чуть подробнее рассмотреть.

Компилятор

Итак, в Next.js (с v12) используется специальный компилятор, написанный на Rust с использованием инструмента SWC. Он супербыстрый и производительный, гораздо круче babel и terser.

В статье https://nextjs.org/docs/advanced-features/compiler можно посмотреть кое-какие опции для точной настройки этого компилятора.

Бандлер

Вместо Webpack можно использовать Turbopack, который в 700 раз быстрее и тоже написан на Rust. Он доступен для Next v13, но нужно специально установить: https://nextjs.org/docs/advanced-features/turbopack

Динамический импорт

Next.js поддерживает динамический импорт модулей, даже предоставляет для этого специальную функцию dynamic из пакета next/dynamic. Она представляет собой комбинацию React.lazy и Suspense, позволяет отображать лоадер, пока загружается компонент и убирает часть кода из клиентского бандла, который грузится на страницу: https://nextjs.org/docs/advanced-features/dynamic-import.

Экспорт статического HTML

С помощью команды next export можно экспортировать ваше приложение в виде набора статических файлов, которые можно положить на любой сервер, чтобы они работали без Node.js. При этом, конечно, теряются многие возможности Next.js, например, SSR. Подробнее здесь: https://nextjs.org/docs/advanced-features/static-html-export.

Настройки импорта и алиасов

Поддерживаются параметры paths и baseUrl из файлов tsconfig.json и jsconfig.json. baseUrl указывает на корень проекта, из которого будут импортироваться пакеты. paths позволяет задать алиасы для импорта: https://nextjs.org/docs/advanced-features/module-path-aliases.

MDX

Поддерживается синтаксис MDX для удобной работы с Markdown: https://nextjs.org/docs/advanced-features/using-mdx


AMP

Поддерживаются AMP-страницы: https://nextjs.org/docs/advanced-features/amp-support/introduction

Настройка Babel

Если требуется настроить Babel специально под нужды проекта, достаточно просто создать файл .babelrc или babel.config.js. Там нужно обязательно указать пресет next/babel, который необходим для работы Next.
https://nextjs.org/docs/advanced-features/customizing-babel-config

Настройка PostCSS

Next по дефолту довольно неплохо обрабатывает ваш CSS, но если требуется большее, можно создать файл postcss.config.json (или .js).
https://nextjs.org/docs/advanced-features/customizing-postcss-config

Собственный сервер

Можно даже запускать собственный сервер вместо сервера Next, хотя звучит это довольно сомнительно, так как при этом мы теряем много полезных вещей. Подробнее: https://nextjs.org/docs/advanced-features/custom-server

Страница ошибки

Если недостаточно страниц 400 и 500, можно переопределить страницу ошибки полностью - создав файл pages/_error.js: https://nextjs.org/docs/advanced-features/custom-error-page

Codemodes

У Next есть функция "режимы кода" (codemodes), которая нужна для того, чтобы модифицировать старую кодовую базу под новые фичи. Например, в старых версиях Next внутри компонента Link нужно было указывать тег a, а в новых версиях это не требуется. Если у вас весь код написан в старом стиле, можно запустить команду


npx @next/codemod@latest new-link


и код, очевидно, будет исправлен.
Подробнее: https://nextjs.org/docs/advanced-features/codemods

Интернационализация

Есть встроенная поддержка интернационализации: https://nextjs.org/docs/advanced-features/i18n-routing

Security Headers

Можно настроить HTTP-заголовки, которые будут передаваться для каждого ответа - в секции headers файла next.config.js: https://nextjs.org/docs/advanced-features/security-headers

#nextjs #документация
🔥5👍2
Next.js. Продвинутые опции - 2

Режим предпросмотра

Представим, что у нас есть статическая страница, которая использует getStaticProps и/или getStaticPaths и рендерится во время сборки. Например, это страница отдельного поста.
Теперь представим, что у нас есть система управления контентом, в которой мы пишем новый пост. Хотелось бы иметь возможность увидеть, как этот пост в итоге будет выглядеть - то есть иметь превью.
То есть мы хотим использовать статическую страничку поста, но динамически, передав ей текущий черновик.
Next такое может, об этом вот здесь: https://nextjs.org/docs/advanced-features/preview-mode

Автоматическая статическая оптимизация (оптимизация статических страниц)

Этот раздел про то, что Next автоматически генерирует html для страниц, которые не используют getServerSideProps.
Тут важно помнить, что если это, например, динамический роут, то страница при рендеринге не получит параметры роута, а после гидратации получит и перерендерится.
Отследить, готовы ли параметры роута, можно, проверив поле router.isReady (хук useRouter).
Подробнее: https://nextjs.org/docs/advanced-features/automatic-static-optimization

Директория src

Фронтендерам привычно использовать для исходников директорию src. В Next же вместо этого мы размещаем все в корне проекта. При желании, можно использовать src, фреймворк это поддерживает. Тогда страницы должны лежать в папке src/pages.
Файлы конфигурации и директория public при этом должны оставаться в корне проекта.
https://nextjs.org/docs/advanced-features/src-directory

Непрерывная интеграция и кэширование сборок

Это о том, как настроить CI workflow, чтобы кэш сохранялся между сборками: https://nextjs.org/docs/advanced-features/ci-build-caching

Multi zones

Словом zone (зона?) обозначается отдельное развертывание (деплой) Next-приложения. Таких зон может быть несколько и они могут объединяться в одно приложение.
Не совсем пока понятно, что это и для чего.
Подробнее: https://nextjs.org/docs/advanced-features/multi-zones

Измерение производительности

Next.js самостоятельно собирает все метрики производительности приложения. Чтобы использовать их, нужно из файла pages/_app.js экспортировать функцию reportWebVitals. Она будет вызываться для каждой измеренной метрики.
Подробнее: https://nextjs.org/docs/advanced-features/measuring-performance

Трассировка выходных файлов

Вроде как позволяет создать сжатую версию приложения со всеми зависимостями в отдельной папке, которую можно развернуть без node_modules.

Подробнее: https://nextjs.org/docs/advanced-features/output-file-tracing

#nextjs #документация
👍5
Next.js. Middleware

С помощью миддлваров мы можем вклиниться в запрос еще до того, как он достигнет нужной страницы и, например, сделать редирект в другое место. Или еще что-нибудь полезное прикрутить вроде аутентификации или AB-тестирования.

Создать такой миддлвар очень просто - нужно просто сделать файлик middleware.js и положить его в корень проекта (рядом с папкой pages). Из этого файла нужно экспортировать функцию middleware.

В качестве параметра функция принимает объект запроса и может либо вернуть объект ответа (NextResponse), либо куда-нибудь перенаправить. Если ничего не вернуть, то запрос выполнится без всяких изменений, как будто и нет никакого миддлвара.

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

В миддлваре, например, удобно проводить проверку на аутентификацию юзера - и если ее нет, то возвращать ошибку или перенаправлять на страничку логина.

Думаю, к этой теме мы еще вернемся, звучит она интересно.

Подробнее: https://nextjs.org/docs/advanced-features/middleware

#nextjs #документация
🔥3👍1
Next.js. Обработка ошибок

Статья в документации: https://nextjs.org/docs/advanced-features/error-handling

Тут ничего особо интересного:

development mode

В режиме разработки приложение будет просто выбрасывать модалку с описанием ошибки.

Ошибки сервера

Если ошибка произошла на стороне сервера, пользователь увидит страницу 500 (или 404, если нужная страница не найдена).

Ошибка клиента

Для обработки клиентских ошибок нам предлагают использовать предохранитель ErrorBoundary. Импортируем его в _app.js и оборачиваем в него компонент страницы.

#nextjs #документация
👍4
Next.js. Индикатор загрузки страницы

Если переход с одной страницы на другую занимает некоторое время (например, подгружаются данные для второй страницы с помощью getServerSideProps), имеет смысл показать пользователю какой-нибудь спиннер, чтобы он понимал, что процесс идет. Такой индикатор легко создать самостоятельно.

По мотивам статьи How To Handle Loading Between Page Changes in Next.js :) (англ.) https://medium.com/@remoteupskill/how-to-manage-loading-elegantly-in-your-next-js-application-5debbfb4cace

Нам потребуется каким-то образом отслеживать начало и окончание перехода между страницами. Логично, что для этого пригодится объект роутера, который можно получить из хука useRouter. У роутера есть поле router.events - это эмиттер событий. Нам нужно подписаться на событие начала перехода (routeChangeStart) и событие окончания перехода (routeChangeComplete).

Инкапсулируем логику отслеживания в виде хука useLoading. Он будет возвращать состояние isLoading, которое будет меняться в зависимости от событий роутера.

Подписка происходит внутри хука useEffect, не забываем также про сброс эффекта.

import { useEffect, useState } from "react";
import { useRouter } from "next/router";

function useLoading() {
const router = useRouter();
const [isLoading, setLoading] = useState(false);

useEffect(function() {
function onStart() {
setLoading(true);
}
function onComplete() {
setLoading(false);
}

router.events.on("routeChangeStart", onStart);
router.events.on("routeChangeComplete", onComplete);

return () => {
router.events.off("routeChangeStart", onStart);
router.events.off("routeChangeComplete", onComplete);
};
}, [router]);

return isLoading;
}


Теперь можно создать компонент спиннера и вывести/скрыть необходимый индикатор в зависимости от состояния isLoading.

const isLoading = useLoading();

if (isLoading) return "Loading...";

return null;


Демо: https://codesandbox.io/p/sandbox/next-page-loader-react-junior-r4n00r?file=%2Fhooks%2FuseLoading.ts&selection=%5B%7B%22endColumn%22%3A7%2C%22endLineNumber%22%3A11%2C%22startColumn%22%3A7%2C%22startLineNumber%22%3A11%7D%5D

В демо есть две странички - Home и About. Для каждой добавлена искусственная задержка загрузки (2 секунды) в getServerSideProps, чтобы виден был индикатор.

Отдельного компонента индикатора нет, он размещен вместе с прочей общей разметкой в файле _app.tsx.

#ссылки #nextjs #примерыкода
👍2🔥2
Стоит ли использовать Redux в Next.js-приложении?

Статья (англ.): https://javascript.plainenglish.io/should-you-use-redux-in-next-js-5e57201c34da

Автор статьи считает, что нам нужно отказаться от Redux в Next.

Причина #1: В нем нет особого смысла, так как благодаря серверному рендерингу мы сразу же, еще до рендеринга страницы, получаем нужные данные.

Причина #2: У Redux есть ряд альтернатив - более легких, нативных и удобных. Например, React Context или Local Storage. В большинстве случаев их функциональности более чем достаточно. Для более сложных сценариев, например, для загрузки данных на клиенте есть библиотеки вроде swr или react-query.

Причина #3: Redux внутри Next сложно хорошо настроить и оптимизировать.

#nextjs #ссылки #redux
👍2
Next.js Middleware: Как оно работает и 5 примеров использования

Статья (англ.): https://javascript.plainenglish.io/next-js-middleware-how-it-works-and-5-real-use-cases-cfacbeb810c9

Про миддлвары в Next мы уже начинали говорить вот тут: https://t.me/react_junior/504

В качестве миддлвара выступает одна простая функция middleware, которая должна экспортироваться из файла middleware.js в корне проекта.

В качестве параметра она получает запрос пользователя (request) и может редиректнуть его, если необходимо.

import { NextResponse } from 'next/server';

export function middleware(request) {
// redirect
return NextResponse.redirect(new URL('new_url', request.url));

// rewrite (сохранить урл, но показать другую страницу)
const url = request.nextUrl.clone();
url.pathname = 'new_url';
return NextResponse.rewrite(url);

// ничего не изменять
return NextResponse.next();
}

Из того же файла можно экспортировать переменную config, в которой, например, можно определить для каких урлов применяется миддлвар (config.matcher).

export const config = {
matcher: '/dashboard/:path*'
}


В статье разбирается базовый функционал миддлвара, а также несколько кейсов его использования:

- аутентификация: получаем данные авторизации из заголовка запроса (request.headers.get('authorization')), если они не совпадают с нужными, переадресуем на страницу авторизации.

- страница "Сайт находится в разработке": если в урле есть секретный параметр, то показываем реальную страницу, если нет - переадресуем всех на страницу "В разработке".

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

- блокировка ботов: по заголовку request.headers['user-agent'] определяем, является ли пользователь ботом.

#nextjs #ссылки
👍3
Как настроить Redux в NextJS

Совсем недавно мы видели мнение, что Redux в Next.js использовать не стоит: https://t.me/c/1218235935/551

Но если вам все-таки хочется, то вот руководство по настройке (англ.): https://medium.com/how-to-react/how-to-setup-redux-in-nextjs-5bce0d82b8de

Выглядит не особо сложно. Помимо обычных настроек Redux нам понадобится еще функция createWrapper из пакета next-redux-wrapper.

const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);

const wrapper = createWrapper(function() {
return store;
});


Теперь нужно обернуть приложение в провайдер хранилища. Сделать это лучше всего в файле _app.js. В провайдер передаем store.

А чтобы все работало, нужно использовать компонент высшего порядка wrapper.withRedux.

import { Provider } from "react-redux";

function MyApp({ Component, pageProps }) {
return (
Provider store={store}
Component {...pageProps}
)
}

export default wrapper.withRedux(MyApp);


Вот и все, теперь можно пользоваться плюшками Redux.

#nextjs #redux #статьи
👍3