Обращаемся ко всем разработчикам Next.js! Хотели бы вы сделать больше с промежуточным ПО? Хотите ли вы иметь возможность перехватывать и переписывать ответ статически сгенерированной страницы Next.js на границе на основе данных о геолокации? Вы также хотите иметь возможность преобразовывать реквизиты страницы на лету?
Теперь вы можете! С помощью Next.js Advanced Middleware. Она работает на базе Netlify Edge Functions, совершенно новой и только на Netlify.
В этом руководстве я покажу вам, как использовать Next.js Advanced Middleware на Netlify для перехвата запроса к статически предварительно созданной странице и переписать HTML-ответ, чтобы изменить текст и реквизиты страницы на основе данных о геолокации.
Развертывание кода учебника на Netlify
Вот демо-сайт, который я создал ранее! Если вы хотите немедленно приступить к работе, вы можете форкнуть репозиторий кода учебника на GitHub и развернуть сайт на своей собственной учетной записи Netlify за считанные секунды. Нажмите на кнопку Deploy to Netlify ниже и попробуйте!
Создайте его самостоятельно
В качестве альтернативы, если вы хотите создать код с нуля, вы можете следовать приведенному ниже руководству, чтобы создать новый проект Next.js, добавить новый статический маршрут и использовать промежуточное ПО для переписывания HTML ответа в The Edge.
Предварительные условия
Прежде чем приступить к работе, проверьте, есть ли у вас инструменты, необходимые для выполнения этого руководства.
- Node.js (рекомендуется LTS)
- GitHub CLI
- Netlify CLI — последняя версия
Настройка проекта
Давайте создадим новое приложение Next.js. Перейдите в терминал и выполните следующую команду, заменив YOUR_PROJECT_NAME
на выбранное вами имя.
npx create-next-app {YOUR_PROJECT_NAME}
Далее, для того чтобы волшебство произошло, нам понадобится пакет @netlify/next
. Выполните следующую команду в терминале, которая установит пакет как зависимость в файл package.json проекта.
npm install @netlify/next
Далее откройте проект в выбранной вами IDE.
Добавьте новый статический маршрут
Next.js предлагает маршрутизацию на основе файлов. Добавление файла JavaScript или TypeScript в каталог pages
создает новый маршрут браузера с тем же именем, что и файл. Создайте новый файл в каталоге pages с именем static.js
и добавьте следующий код.
// pages/static.js
const Page = () => {
return (
<main>
<h1 id="message">A static page</h1>
</main>
);
};
export default Page;
Вернувшись в терминал, запустите сервер разработки с помощью Netlify CLI, выполнив следующую команду.
netlify dev
Автоматически откроется вкладка браузера на localhost:8888. Перейдите на http://localhost:8888/static в вашем браузере, и там будет ваша новая статическая страница.
Мы собираемся предварительно сгенерировать эту страницу во время сборки с некоторыми базовыми данными, прежде чем преобразовать ее с помощью Next.js Advanced Middleware. Экспортируя функцию getStaticProps
из файла страницы, Next.js будет предварительно генерировать эту страницу во время сборки, используя данные, возвращаемые getStaticProps()
.
Добавьте следующий код в static.js
и передайте реквизит message
в функцию Page
.
// pages/static.js
export async function getStaticProps() {
return {
props: {
message: "This is a static page — and now this is a prop!",
},
};
}
const Page = ({ message }) => {
return (
<main>
<h1 id="message">{message}</h1>
</main>
);
};
export default Page;
И чтобы убедиться, что все подключено, вот наша обновленная статическая страница, использующая реквизит message.
Далее, переходим к промежуточному программному обеспечению!
Переписывание HTML и преобразование данных страницы
Промежуточное ПО в Next.js позволяет запускать код до завершения HTTP-запроса — оно находится в середине запроса и ответа. Вы можете создать файл промежуточного ПО в Next.js, используя JavaScript или TypeScript, и для целей этого руководства мы будем писать промежуточное ПО на TypeScript.
В корне вашего проекта создайте новый файл и назовите его middleware.ts
. Этот файл будет запускаться на каждый запрос при работе вашего приложения — включая страницы, статические файлы и активы. В middleware.ts
добавьте следующий код. Мы импортируем тип NextRequest
, который представляет входящий HTTP-запрос, экспортируем асинхронную функцию middleware
и передаем запрос как nextRequest
в функцию, которая является объектом NextRequest
.
// middleware.ts
import type { NextRequest } from "next/server";
export async function middleware(nextRequest: NextRequest) {
}
В этом демо мы хотим, чтобы промежуточное ПО запускалось на маршруте с именем static
. Давайте получим имя пути из запроса и подготовим функцию, которая будет делать что-то, когда имя пути начинается с static
.
// middleware.ts
import type { NextRequest } from "next/server";
export async function middleware(nextRequest: NextRequest) {
const pathname = nextRequest.nextUrl.pathname;
if (pathname.startsWith("/static")) {
// do something here
}
}
Далее настало время для магии Netlify. Давайте перепишем HTML статической страницы, которую мы создали ранее. В верхней части файла импортируйте MiddlewareRequest
как именованный импорт из @netlify/next
.
// middleware.ts
import type { NextRequest } from "next/server";
import { MiddlewareRequest } from "@netlify/next";
export async function middleware(nextRequest: NextRequest) {
const pathname = nextRequest.nextUrl.pathname;
if (pathname.startsWith("/static")) {
// do something here
}
}
Внутри функции middleware инициализируем новый Netlify MiddlewareRequest
, передавая исходный NextRequest
в качестве nextRequest
.
import type { NextRequest } from "next/server";
import { MiddlewareRequest } from "@netlify/next";
export async function middleware(nextRequest: NextRequest) {
const pathname = nextRequest.nextUrl.pathname;
const middlewareRequest = new MiddlewareRequest(nextRequest);
if (pathname.startsWith("/static")) {
// do something here
}
}
Это улучшает исходный объект запроса, добавляя все хорошее, что есть в Netlify Edge Functions. Netlify Edge Functions очень похожи на бессерверные функции. Вы можете написать их на JavaScript или TypeScript, но вместо использования Node.js под капотом, они работают на базе Deno — среды выполнения с открытым исходным кодом, построенной на веб-стандартах — и выполняются на ближайшем к запросу сервере. Это позволяет полностью персонализировать страницы на The Edge в Next.js, без необходимости использовать getServerSideProps()
в маршрутах страниц. Это также работает с Incremental Static Regeneration.
Теперь наш объект NextRequest
выровнен с объектом Netlify MiddlewareRequest
, у нас есть возможность изменять HTTP-ответ до его возвращения — потому что мы можем фактически отправить запрос на источник, чтобы получить его и работать с ним.
Добавьте следующий код внутри оператора if
, и давайте распакуем, что он делает.
// middleware.ts
import type { NextRequest } from "next/server";
import { MiddlewareRequest } from "@netlify/next";
export async function middleware(nextRequest: NextRequest) {
const pathname = nextRequest.nextUrl.pathname;
const middlewareRequest = new MiddlewareRequest(nextRequest);
if (pathname.startsWith("/static")) {
const response = await middlewareRequest.next();
const message = `This was a static page but has been transformed in
${nextRequest?.geo?.city},
${nextRequest?.geo?.country} using
@netlify/next in middleware.ts!`;
response.replaceText("#message", message);
response.setPageProp("message", message);
return response;
}
}
Если имя пути начинается с static
, мы получаем следующий ответ в цепочке HTTP, ожидая middlewareRequest.next()
— это наша статическая страница — и присваиваем его переменной response
. Затем, используя геолокационные данные из nextRequest
, мы создаем новое персонализированное сообщение, заменяющее содержимое статической страницы.
Next.js Advanced Middleware от Netlify включает функцию replaceText
, а также имеет поддержку более мощных преобразований с помощью потокового трансформатора HTML Rewriter. Чтобы получить доступ к сообщению из DOM в функции middleware, мы добавляем ID к узлу DOM, содержащему сообщение, которое мы хотим преобразовать на статической странице.
// pages/static.js
const Page = ({ message }) => {
return (
<main>
<h1 id="message">{message}</h1>
</main>
);
};
Затем мы выполняем replaceText
в ответе, передавая в DOM ID, который мы добавили к сообщению в static.js
, и новое сообщение, которое мы создали. Чтобы убедиться, что гидратированное содержимое на клиенте соответствует HTML, отображаемому на сервере (и чтобы избежать ошибки React hydration error
), мы также можем обновить реквизиты страницы с помощью setPageProp
, чтобы обновить данные сообщения на странице.
Наконец, верните ответ
! Вернитесь в браузер и посмотрите на обновленное сообщение на ранее статически сгенерированной странице.
Сообщение было преобразовано в файле промежуточного ПО, а HTML статической страницы был переписан. Более того, реквизит страницы также был обновлен! Просмотрите исходный текст страницы, найдите NEXT_DATA
в DOM и проверьте обновленный реквизит сообщения страницы — все это с помощью Next.js Advanced Middleware от Netlify.
Давайте развернем Netlify, чтобы посмотреть, как HTML-перезапись происходит в реальном времени на живом URL.
Подключение вашего git-репозитория
У нас есть несколько вариантов того, как развернуть проект Next.js в Netlify. В этом руководстве мы подключимся к новому git-репозиторию, чтобы бесплатно получить CI/CD и настройки.
Проекты Next.js поставляются с уже инициализированным git-репо. Поставьте и зафиксируйте свои файлы с помощью следующих команд.
git add . # stage your files
git commit -m 'Initial commit' # commit your files with a commit message
Следующие шаги помогут вам добавить ваш репозиторий в GitHub с помощью GitHub CLI — но вы можете отправить свой проект в GitHub любым удобным для вас способом.
Выполните следующую команду в терминале, чтобы создать новый репозиторий, подключенный к вашей учетной записи GitHub:
gh repo create
В ответ на запрос о типе репозитория, который вы хотите создать, выберите: Push an existing local repository to GitHub
. Следуйте оставшимся подсказкам, чтобы заполнить соответствующие детали проекта. Теперь вы готовы к развертыванию в Netlify!
Развертывание в Netlify с помощью Netlify CLI
Если вы еще не вошли в Netlify CLI, выполните следующую команду в терминале и следуйте подсказкам для авторизации в Netlify (откроется окно браузера).
netlify login
Далее выполните следующую команду для инициализации нового проекта на Netlify.
netlify init
Заполните следующие подсказки для настройки нового проекта:
- Что вы хотите сделать?
Создать и настроить новый сайт
. - Команда:
YOUR_TEAM
- Название сайта (необязательно):
CHOOSE_UNIQUE_SITE_NAME
Netlify CLI автоматически определит, что вы используете Next.js, поэтому следующие подсказки будут предварительно заполнены. Нажмите Enter, чтобы использовать значения по умолчанию.
- Ваша команда сборки (hugo build/yarn run build/etc):
(next build)
. - Каталог для развертывания (пустой для текущего каталога):
(.next)
- Папка функций Netlify:
(netlify/functions)
.
Подождите несколько секунд… и ваш новый сайт развернут! 🎉 Теперь вы можете продемонстрировать свои новые навыки персонализации в Next.js, отправив живой URL своим друзьям.
Узнайте больше
Посетите официальную документацию Netlify, чтобы узнать о том, что теперь возможно с Next.js Advanced Middleware — только на Netlify.