Статические файлы
Статические файлы — те, что отдаются клиенту как есть, без обработки: HTML-страницы, стили, скрипты, картинки. Fastify сам по себе их не раздаёт, для этого есть официальный плагин @fastify/static. Например, рядом с API можно положить простую страницу блога, которая загружает статьи через fetch.
Установка
npm install @fastify/staticПапка public
Создайте в корне проекта папку public и файл public/index.html:
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Блог</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<h1>Блог</h1>
<ul id="posts"></ul>
</body>
</html>Рядом положите public/style.css с любыми стилями. Структура проекта:
blog-api/
public/
index.html
style.css
src/
app.jsПодключение
Зарегистрируйте плагин в src/app.js:
// src/app.js
import path from 'node:path';
import fastifyStatic from '@fastify/static';
app.register(fastifyStatic, {
root: path.join(import.meta.dirname, '..', 'public'),
prefix: '/',
});root — абсолютный путь к папке. import.meta.dirname — папка текущего файла (src), поэтому '..' поднимается в корень проекта. Откройте http://localhost:3000/ — появится страница «Блог», а http://localhost:3000/style.css вернёт файл стилей.
Префикс
Опция prefix задаёт начало адреса файлов. С prefix: '/assets/' файл public/style.css будет доступен по адресу /assets/style.css. Префикс помогает не путать файлы с маршрутами API.
Отправка файла из маршрута
Плагин добавляет метод reply.sendFile() — им можно отдать файл из папки root в обычном маршруте:
// src/routes/pages.js
export default async function pageRoutes(app) {
app.get('/about', async (request, reply) => {
return reply.sendFile('about.html');
});
}Создайте public/about.html, подключите pageRoutes в src/app.js и откройте http://localhost:3000/about — появится содержимое этого файла.
Частая ошибка
Не пишите в root относительный путь вроде 'public': плагин рассчитан на абсолютный путь, а относительный зависит от папки, из которой запущен процесс, и при запуске из другой папки файлы перестанут находиться. Всегда стройте путь через import.meta.dirname и path.join.