React Junior
207 subscribers
37 photos
462 links
Изучение React с нуля
加入频道
Next.js. Image. Источник изображения

Image может работать и с локальными, и с удаленными файлами, причем с локальными - больше плюшек.

Локальные изображения

Изображения проекта должны храниться в папке public. Импортируем их в нужный компонент и передаем в проп src компонента Image.

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

Динамический импорт не поддерживается.

Удаленные изображения

В src можно указать и обычный урл (относительный или абсолютный). Если используются абсолютные пути, то домены обязательно нужно добавить в файл next.config.js в секцию images.remotePatterns.

module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
},
],
},
}


#nextjs #серверныйрендеринг #документация
👍5
Next.js. Image. srcset

Компонент Image рендерит стандартный тег img и проставляет для него массу полезных атрибутов, например, srcset. Что именно в нем будет, зависит от пропа sizes (https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes). Если этот проп не передан, будет всего пара размеров, но может быть и очень большой список.

srcset генерируется и для локальных, и для удаленных изображений.

Видео (англ.): https://www.youtube.com/watch?v=R4sdWUI3-mY&ab_channel=BrunoAntunes

В начале видео очень подробно и понятно рассказывается об атрибутах srcset и sizes. Вторая часть (про Next.js) немного устарела, с момента записи произошли некоторые изменения.

#nextjs #серверныйрендеринг #документация
👍3🔥1
Next.js. Image. Ленивая загрузка

Изображения, сгенерированные компонентом Image по умолчанию грузятся "лениво" - только когда попадают во вьюпорт.
Если указать проп placeholder=blur, то до окончательной загрузки будет отображаться размытая версия изображения. Для локальных изображений она сгенерируется автоматически, а для всех остальных можно указать нужный адрес в пропе blurDataURL.

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

Еще несколько полезных пропсов:

- fill - привязывает размеры изображения к размерам родительского контейнера. Работает как position: absolute + inset: 0.

- quality - позволяет управлять качеством картинки (от 1 до 100). По умолчанию 75.

- priority - указывает, что картинку нужно загрузить как можно быстрее, без ленивой загрузки. Следует использовать для Largest Contentful Paint.

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

Мы можем самостоятельно настроить урлы изображений, которые попадают в конечный srcset, передав свой собственный лоадер в проп loader.

Лоадер это обычная функция, которая принимает адрес (src), ширину и качество (quality). И должна вернуть урл изображения для заданной ширины. Если у вас есть апи, который умеет изменять размер и качество изображений, здесь можно его использовать. Но в целом у Next.js как будто нормальный дефолтный лоадер.

Откуда берутся значения ширины? Из настроек images.deviceSizes и image.imageSizes в файле next.config.js. По умолчанию там уже заданы большие наборы, при необходимости их можно переопределить. Оба эти массива объединяются для формирования srcset.

#nextjs #серверныйрендеринг #документация
👍2🔥1
Next.js. Image. Форматы изображений

Последняя приятная плюшка компонента Image, о которой я упомяну - это автоматическое использование производительных форматов. Если браузер клиента поддерживает webp, то изображение будет в webp, даже если вы сохранили его в jpg.

Настроить разрешенные форматы можно в next.config.js в поле images.formats.

#nextjs #серверныйрендеринг #документация
🔥3👍2
Next.js. Оптимизация шрифтов

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

Все шрифты хостятся на вашем сервере (гугловские шрифты загружаются во время сборки и тоже помещаются на сервер).

Для работы понадобится пакет @next/font.

Локальные шрифты

Для локальных шрифтов используем функцию localFont. Работает и с одним файлом, и с несколькими, если разные начертания находятся в разных файлах:

import localFont from '@next/font/local';

const myFont1 = localFont({ src: './my-font.woff2' });

const myFont2 = localFont({
src: [
{
path: './Roboto-Regular.woff2',
weight: '400',
style: 'normal',
},
{
path: './Roboto-Italic.woff2',
weight: '400',
style: 'italic',
},
]
});


Функция localFont возвращает объект с полями className и style.

Применять такой загруженный шрифт нужно с помощью сгенерированного имени класса. Для нужного элемента в разметке устанавливаем проп className={myFont.className}. Теперь для этого элемента установлено нужное значение font-family.

Google-шрифты

Для гугл-шрифтов нужно импортировать функции из пакета @next/font/google. Потребуется указать подмножество шрифта и при необходимости настройки, например, вес и стиль:

import { Inter } from '@next/font/google';
import { Roboto } from '@next/font/google';

const inter = Inter({ subsets: ['latin'] })
const roboto = Roboto({
weight: '400',
subsets: ['latin'],
});
const roboto1 = Roboto({
weight: ['400', '700'],
style: ['normal', 'italic'],
subsets: ['latin'],
});


Используем эти шрифты точно так же, через className.

Шрифты в head

Можно использовать и более привычный вариант - указать шрифты в теге style с помощью синтаксиса jsx. Это следует делать в файле _app.tsx. Значение берем из myFont.style.fontFamily. Важно сделать блок со стилями глобальным (атрибут global, чтобы стили были помещены в head.

Демо: https://codesandbox.io/p/sandbox/wizardly-dream-5gv4mx?file=%2Fpages%2Findex.tsx&selection=%5B%7B%22endColumn%22%3A37%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A37%2C%22startLineNumber%22%3A3%7D%5D

В демке для документа установлен глобальный стиль с font-family: Inter (файл pages/_app.tsx). На главной странице (pages/index.tsx) загружен шрифт Pacifico. Он установлен для одного абзаца с помощью className.

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

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

Соберем в одном месте типы, которые использует Next:

Данные для серверного рендеринга - GetStaticProps, GetStaticPaths, GetServerSideProps

import { GetStaticProps, GetStaticPaths, GetServerSideProps } from 'next';
export const getStaticProps: GetStaticProps = async function (context) {
// ...
}
export const getStaticPaths: GetStaticPaths = async function () {
// ...
}
export const getServerSideProps: GetServerSideProps = async function (context) {
// ...
}


API-роуты - NextApiRequest, NextApiResponse

import type { NextApiRequest, NextApiResponse } from 'next'

export default function handler(req: NextApiRequest, res: NextApiResponse) {
res.status(200).json({ name: 'John Doe' })
}


Тип NextApiResponse может также принимать обобщенный тип данных ответа.

Компонент App - AppProps

import type { AppProps } from 'next/app'

export default function MyApp({ Component, pageProps }: AppProps) {
// ...
}


#nextjs #документация #typescript
👍3🔥1
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