Интеграция Strapi с фронтендом (React/Vue/Next.js/Nuxt.js)

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Интеграция Strapi с фронтендом (React/Vue/Next.js/Nuxt.js)
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Интеграция Strapi с фронтендом (React/Vue/Next.js/Nuxt.js)

Strapi работает как отдельный headless API-сервер. Фронтенд обращается к нему по HTTP — через REST или GraphQL. Ключевые задачи интеграции: типобезопасный клиент, кэширование на уровне фреймворка, on-demand ревалидация и проксирование запросов через BFF для скрытия API-токенов.

Базовый API клиент

// lib/strapi.ts
const STRAPI_URL = process.env.STRAPI_URL!
const API_TOKEN = process.env.STRAPI_API_TOKEN!

interface StrapiResponse<T> {
  data: T
  meta: {
    pagination?: { page: number; pageSize: number; pageCount: number; total: number }
  }
}

export async function strapi<T>(
  endpoint: string,
  init?: RequestInit & { next?: { tags?: string[]; revalidate?: number } }
): Promise<StrapiResponse<T>> {
  const url = `${STRAPI_URL}/api${endpoint}`

  const response = await fetch(url, {
    headers: {
      Authorization: `Bearer ${API_TOKEN}`,
      'Content-Type': 'application/json',
    },
    ...init,
  })

  if (!response.ok) {
    throw new Error(`Strapi error ${response.status}: ${await response.text()}`)
  }

  return response.json()
}

// Вспомогательные функции
export function getMediaURL(path: string | null | undefined) {
  if (!path) return null
  if (path.startsWith('http')) return path
  return `${STRAPI_URL}${path}`
}

Server Components (Next.js App Router)

// app/articles/page.tsx
import { strapi } from '@/lib/strapi'
import type { Article, StrapiMedia } from '@/types/strapi'

interface ArticleListData {
  id: number
  attributes: {
    title: string
    slug: string
    excerpt: string
    publishedAt: string
    cover: { data: { id: number; attributes: StrapiMedia } | null }
  }
}

export default async function ArticlesPage({
  searchParams,
}: {
  searchParams: { page?: string; category?: string }
}) {
  const page = Number(searchParams.page) || 1
  const categoryFilter = searchParams.category
    ? `&filters[category][slug][$eq]=${searchParams.category}`
    : ''

  const { data: articles, meta } = await strapi<ArticleListData[]>(
    `/articles?populate=cover,category&sort=publishedAt:desc&pagination[page]=${page}&pagination[pageSize]=12${categoryFilter}`,
    { next: { tags: ['articles'], revalidate: 3600 } }
  )

  return (
    <div>
      <ArticleGrid articles={articles} />
      <Pagination meta={meta.pagination} />
    </div>
  )
}

export const revalidate = 3600

ISR + On-demand Revalidation

// app/articles/[slug]/page.tsx
export default async function ArticlePage({ params }: { params: { slug: string } }) {
  const { data } = await strapi<ArticleListData[]>(
    `/articles?filters[slug][$eq]=${params.slug}&populate=cover,author,category,tags`,
    { next: { tags: [`article-${params.slug}`] } }
  )

  const article = data[0]
  if (!article) notFound()

  return <Article article={article} />
}

export async function generateStaticParams() {
  const { data } = await strapi<{ attributes: { slug: string } }[]>(
    '/articles?fields[0]=slug&pagination[pageSize]=200'
  )
  return data.map(item => ({ slug: item.attributes.slug }))
}
// app/api/revalidate/route.ts — принимает вебхук от Strapi
import { revalidateTag, revalidatePath } from 'next/cache'

export async function POST(req: Request) {
  const { model, entry } = await req.json()

  // Инвалидировать по тегу
  revalidateTag(model)  // например, 'article'

  // Инвалидировать конкретную страницу
  if (entry?.slug) {
    revalidatePath(`/articles/${entry.slug}`)
    revalidateTag(`article-${entry.slug}`)
  }

  return Response.json({ revalidated: true })
}

Client-side запросы (React)

// hooks/useArticles.ts
'use client'
import useSWR from 'swr'

const fetcher = (url: string) =>
  fetch(url).then(r => r.json())

export function useArticles(category?: string) {
  const query = category ? `?filters[category][slug][$eq]=${category}` : ''
  const { data, error, isLoading } = useSWR(
    `/api/articles${query}`,  // через Next.js API proxy
    fetcher
  )

  return {
    articles: data?.data || [],
    isLoading,
    error,
  }
}
// app/api/articles/route.ts — proxy для клиентских запросов
export async function GET(req: Request) {
  const url = new URL(req.url)
  const params = url.searchParams.toString()

  const response = await fetch(
    `${process.env.STRAPI_URL}/api/articles?${params}&populate=cover`,
    { headers: { Authorization: `Bearer ${process.env.STRAPI_API_TOKEN}` } }
  )

  const data = await response.json()
  return Response.json(data)
}

TypeScript типы для Strapi ответов

// types/strapi.ts
export interface StrapiMedia {
  name: string
  url: string
  alternativeText: string | null
  width: number
  height: number
  formats: {
    thumbnail?: StrapiMediaFormat
    small?: StrapiMediaFormat
    medium?: StrapiMediaFormat
    large?: StrapiMediaFormat
  }
}

export interface StrapiMediaFormat {
  url: string
  width: number
  height: number
}

export interface StrapiEntity<T> {
  id: number
  attributes: T
}

export interface Article {
  title: string
  slug: string
  content: string
  excerpt: string
  publishedAt: string
  cover: { data: StrapiEntity<StrapiMedia> | null }
  author: { data: StrapiEntity<{ name: string; avatar: any }> | null }
}

Сроки

Интеграция Strapi с Next.js (ISR, вебхуки, TypeScript типы) — 2–3 дня.