Введение
Headless CMS архитектура становится стандартом для современных веб-приложений. Она обеспечивает гибкость, масштабируемость и возможность использовать один бэкенд для множества фронтенд-платформ.
В этом руководстве мы рассмотрим интеграцию Nuxt 4 — мощного Vue.js фреймворка — с Directus, open-source headless CMS, который предоставляет удобный интерфейс для управления контентом и мощное REST/GraphQL API.
Почему Nuxt 4 + Directus?
Nuxt 4 предлагает серверный рендеринг (SSR), статическую генерацию (SSG), оптимизированную производительность и отличный Developer Experience. Directus даёт полный контроль над данными, гибкую схему и TypeScript SDK из коробки.
Преимущества связки Nuxt 4 + Directus:
- TypeScript типизация для всего стека
- SSR/SSG для оптимального SEO
- Гибкая схема данных без ограничений CMS
- REST и GraphQL API на выбор
- Open-source решения без vendor lock-in
- Docker-friendly для простого деплоя
Настройка Directus
Directus можно запустить локально через Docker Compose. Пример минимальной конфигурации:
services:
directus:
image: directus/directus:latest
ports:
- 8055:8055
environment:
KEY: "your-secret-key"
SECRET: "your-secret-key"
DB_CLIENT: "pg"
DB_HOST: "postgis"
DB_PORT: "5432"
DB_DATABASE: "directus"
DB_USER: "directus"
DB_PASSWORD: "directus"
ADMIN_EMAIL: "admin@example.com"
ADMIN_PASSWORD: "admin123"
depends_on:
- postgisПосле запуска Directus будет доступен на http://localhost:8055. Создайте коллекции для вашего контента — например, "articles", "projects", "pages".
Интеграция с Nuxt 4
Установите Directus SDK:
yarn add @directus/sdkСоздайте composable для работы с Directus API:
// composables/useDirectus.ts
import { createDirectus, rest, readItems } from '@directus/sdk'
export const useDirectus = () => {
const config = useRuntimeConfig()
const client = createDirectus(config.public.directusUrl)
.with(rest())
return {
client,
readItems
}
}Настройте конфигурацию в nuxt.config.ts:
export default defineNuxtConfig({
runtimeConfig: {
public: {
directusUrl: process.env.NUXT_PUBLIC_DIRECTUS_URL || 'http://localhost:8055'
}
}
})TypeScript типизация
Создайте типы для ваших Directus коллекций:
// types/directus.ts
export interface Article {
id: string
status: string
title: string
slug: string
content: string
author: string
published_date: string
thumbnail: string
category: string
}
export interface DirectusSchema {
articles: Article[]
// другие коллекции
}Используйте типы в composable:
import type { DirectusSchema } from '~/types/directus'
export const useDirectus = () => {
const client = createDirectus<DirectusSchema>(config.public.directusUrl)
.with(rest())
return { client, readItems }
}SSR и ISR стратегии
Для оптимальной производительности используйте серверные API endpoints:
// server/api/articles.ts
import { createDirectus, rest, readItems } from '@directus/sdk'
import type { DirectusSchema } from '~/types/directus'
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig()
const client = createDirectus<DirectusSchema>(config.public.directusUrl)
.with(rest())
const articles = await client.request(
readItems('articles', {
filter: { status: { _eq: 'published' } },
sort: ['-published_date'],
limit: 10
})
)
return articles
})На странице используйте useFetch для SSR:
// pages/blog/index.vue
<script setup lang="ts">
const { data: articles } = await useFetch('/api/articles')
</script>
<template>
<div v-for="article in articles" :key="article.id">
<h2>{{ article.title }}</h2>
</div>
</template>Кеширование и оптимизация
Используйте кеширование для снижения нагрузки на Directus:
// server/api/articles.ts
export default defineEventHandler(async (event) => {
// Кеширование на 5 минут
setResponseHeader(event, 'Cache-Control', 'public, max-age=300')
return cachedEventHandler(async () => {
// fetch from Directus
}, {
maxAge: 60 * 5, // 5 минут
name: 'articles'
})
})Для production используйте Redis для кеширования через Nitro storage:
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
storage: {
redis: {
driver: 'redis',
host: 'localhost',
port: 6379
}
}
}
})Best Practices
- Используйте серверные API endpoints для чувствительных данных
- Типизируйте все Directus коллекции
- Применяйте кеширование для часто запрашиваемых данных
- Используйте фильтры и лимиты в запросах к Directus
- Настройте переменные окружения для разных сред (dev/prod)
- Включите компрессию для API ответов
- Используйте ISR (Incremental Static Regeneration) для статического контента
Заключение
Связка Nuxt 4 + Directus обеспечивает мощное и гибкое решение для создания современных веб-приложений. TypeScript типизация, SSR/SSG возможности и гибкая архитектура позволяют создавать производительные и масштабируемые проекты.
В ExtTeam мы успешно используем этот стек для множества проектов — от корпоративных сайтов до высоконагруженных e-commerce платформ.
