Интеграция Sanity с Next.js / Nuxt.js / Remix

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

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

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Интеграция Sanity с Next.js / Nuxt.js / Remix
Средняя
~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

Интеграция Sanity с Next.js / Nuxt.js / Remix

Sanity работает через HTTP API — любой фреймворк может читать контент. Официальные библиотеки: next-sanity для Next.js, @sanity/client для остальных.

Next.js App Router

npm install next-sanity @sanity/client @portabletext/react @sanity/image-url
// lib/sanity/client.ts
import { createClient } from 'next-sanity'

export const client = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || 'production',
  apiVersion: '2024-01-01',
  useCdn: process.env.NODE_ENV === 'production',
})

// Для черновиков (preview mode)
export const previewClient = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || 'production',
  apiVersion: '2024-01-01',
  useCdn: false,
  token: process.env.SANITY_API_TOKEN,
  perspective: 'previewDrafts',
})
// app/posts/[slug]/page.tsx
import { client } from '@/lib/sanity/client'
import { groq } from 'next-sanity'
import { draftMode } from 'next/headers'

const query = groq`*[_type == "post" && slug.current == $slug][0] {
  _id, title, body, publishedAt,
  "author": author->{ name },
  "slug": slug.current
}`

export default async function PostPage({ params }: { params: { slug: string } }) {
  const { isEnabled } = draftMode()
  const activeClient = isEnabled ? previewClient : client

  const post = await activeClient.fetch(query, { slug: params.slug }, {
    next: { tags: [`post-${params.slug}`] },
  })

  if (!post) notFound()
  return <Article post={post} />
}

export async function generateStaticParams() {
  const slugs = await client.fetch<string[]>(`*[_type == "post"].slug.current`)
  return slugs.filter(Boolean).map(slug => ({ slug }))
}

On-demand Revalidation

// app/api/revalidate/route.ts
import { revalidateTag } from 'next/cache'
import { parseBody } from 'next-sanity/webhook'

export async function POST(req: Request) {
  try {
    const { isValidSignature, body } = await parseBody<{ _type: string; slug?: { current: string } }>(
      req,
      process.env.SANITY_WEBHOOK_SECRET!
    )

    if (!isValidSignature) {
      return Response.json({ message: 'Invalid signature' }, { status: 401 })
    }

    if (body._type === 'post') {
      revalidateTag('posts')
      if (body.slug?.current) {
        revalidateTag(`post-${body.slug.current}`)
      }
    }

    return Response.json({ revalidated: true })
  } catch (err) {
    return Response.json({ message: 'Invalid request' }, { status: 400 })
  }
}

Nuxt 3 (@nuxt/sanity)

npm install @nuxtjs/sanity
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/sanity'],
  sanity: {
    projectId: process.env.NUXT_PUBLIC_SANITY_PROJECT_ID,
    dataset: 'production',
    apiVersion: '2024-01-01',
    useCdn: process.env.NODE_ENV === 'production',
  },
})
<!-- pages/posts/[slug].vue -->
<template>
  <article v-if="post">
    <h1>{{ post.title }}</h1>
    <SanityContent :blocks="post.body" />
  </article>
</template>

<script setup lang="ts">
const { $sanity } = useNuxtApp()
const route = useRoute()

const { data: post } = await useAsyncData(`post-${route.params.slug}`, () =>
  $sanity.fetch(
    `*[_type == "post" && slug.current == $slug][0] { title, body }`,
    { slug: route.params.slug }
  )
)
</script>

Remix

// app/routes/posts.$slug.tsx
import { json, type LoaderFunctionArgs } from '@remix-run/node'
import { useLoaderData } from '@remix-run/react'
import { createClient } from '@sanity/client'

const client = createClient({
  projectId: process.env.SANITY_PROJECT_ID!,
  dataset: 'production',
  apiVersion: '2024-01-01',
  useCdn: true,
})

export async function loader({ params }: LoaderFunctionArgs) {
  const post = await client.fetch(
    `*[_type == "post" && slug.current == $slug][0] { title, body, publishedAt }`,
    { slug: params.slug }
  )

  if (!post) throw new Response('Not Found', { status: 404 })
  return json(post)
}

export default function PostPage() {
  const post = useLoaderData<typeof loader>()
  return (
    <article>
      <h1>{post.title}</h1>
    </article>
  )
}

Санировать изображения через Sanity Image CDN

import imageUrlBuilder from '@sanity/image-url'
import { client } from '@/lib/sanity/client'

const builder = imageUrlBuilder(client)

export function sanityImageUrl(source: any) {
  return builder.image(source)
}

// Использование
const url = sanityImageUrl(post.mainImage)
  .width(800)
  .height(450)
  .crop('entropy')   // умная обрезка
  .auto('format')    // WebP если поддерживается
  .quality(80)
  .url()

Сроки

Интеграция Sanity с Next.js App Router (ISR, webhooks, preview mode) — 1–2 дня. Для Nuxt или Remix — 1 день.