Разработка SSG (Static Site Generation) для сайта
Static Site Generation — генерация HTML-файлов на этапе сборки, а не при каждом запросе. Сервер отдаёт готовый HTML напрямую с CDN, без серверного рендера, без баз данных в критическом пути. Результат: минимальный TTFB, масштабирование без дополнительных серверов, максимальная надёжность.
SSG подходит для контента, который обновляется редко или может обновляться по расписанию: документация, блоги, лендинги, маркетинговые сайты, портфолио, каталоги.
Инструменты и их применение
| Инструмент | Стек | Когда использовать |
|---|---|---|
| Next.js (output: export) | React | Уже используете React/Next.js |
| Nuxt (nitro static) | Vue | Уже используете Vue/Nuxt |
| Astro | Любой/None | Контентный сайт, минимум JS |
| SvelteKit (adapter-static) | Svelte | Svelte-проекты |
| Eleventy | Нет фреймворка | Максимальная гибкость шаблонов |
| Hugo | Go | Тысячи страниц, скорость сборки критична |
Для большинства задач мы рекомендуем Astro — он генерирует нулевой клиентский JS по умолчанию и поддерживает компоненты React/Vue/Svelte одновременно.
Реализация на Astro
---
// src/pages/blog/[slug].astro
import { getCollection, type CollectionEntry } from 'astro:content';
import BlogLayout from '@/layouts/BlogLayout.astro';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(post => ({
params: { slug: post.slug },
props: { post },
}));
}
interface Props { post: CollectionEntry<'blog'>; }
const { post } = Astro.props;
const { Content, headings, remarkPluginFrontmatter } = await post.render();
---
<BlogLayout
title={post.data.title}
description={post.data.description}
publishedAt={post.data.publishedAt}
readingTime={remarkPluginFrontmatter.minutesRead}
>
<Content />
</BlogLayout>
// src/content/config.ts — типизированная схема контента
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string().max(160),
publishedAt: z.date(),
tags: z.array(z.string()),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };
Интеграция с Headless CMS
Статические сайты не означают статичный контент. Данные берутся при сборке из API:
// src/lib/cms.ts — интеграция с Contentful
import contentful from 'contentful';
const client = contentful.createClient({
space: import.meta.env.CONTENTFUL_SPACE_ID,
accessToken: import.meta.env.CONTENTFUL_ACCESS_TOKEN,
});
export async function getProducts(): Promise<Product[]> {
const entries = await client.getEntries<ProductFields>({
content_type: 'product',
order: ['-sys.createdAt'],
limit: 1000,
});
return entries.items.map(item => ({
id: item.sys.id,
name: item.fields.name,
slug: item.fields.slug,
price: item.fields.price,
image: `https:${item.fields.image.fields.file.url}`,
}));
}
При каждом деплое (или по webhook от CMS) сайт пересобирается с актуальными данными.
Оптимизация изображений
---
import { Image } from 'astro:assets';
import heroImage from '@/assets/hero.jpg';
---
<!-- Astro автоматически конвертирует в WebP/AVIF, добавляет srcset -->
<Image
src={heroImage}
alt="Описание"
width={1200}
height={600}
format="avif"
quality={80}
/>
Для внешних изображений из CMS — через <Image src={url} /> с настроенными доменами в astro.config.mjs.
Инкрементальная сборка для больших сайтов
При тысячах страниц полная пересборка занимает минуты. Решения:
- Astro Content Collections с кэшем — пересобираются только изменённые страницы
- Turbo Remote Caching — кэш сборки между CI-запусками
- Partial builds через webhook: Contentful/Sanity вызывает деплой только при изменении конкретного контента
# Netlify: ребилд только при изменении определённых полей CMS
{
"build": {
"command": "npm run build",
"publish": "dist"
},
"functions": {
"directory": "netlify/functions"
}
}
Деплой
SSG-сайт — это директория со статическими файлами. Деплоится куда угодно:
- Cloudflare Pages — бесплатный план, 500 сборок/месяц, глобальный CDN
- Netlify — простой workflow, встроенные формы и функции
- Vercel — оптимально для Next.js
- GitHub Pages — через Actions для open-source проектов
- S3 + CloudFront — для AWS-инфраструктуры с полным контролем
Сроки реализации
- Неделя 1: выбор инструмента, структура проекта, схема контента, дизайн-система
- Неделя 2: шаблоны страниц, интеграция с CMS, SEO (sitemap, robots.txt, OpenGraph)
- Неделя 3: оптимизация изображений, Search (Pagefind или Algolia DocSearch), деплой pipeline
- Неделя 4: тестирование производительности, настройка webhook-пересборок, обучение команды контента







