Для интернет-магазинов производительность и SEO — ключ к продажам. Next.js 15 предлагает прорывные возможности в обеих областях. В этой статье мы подробно разберём, как использовать Next.js 15 в современных интернет-магазинах.
Новые возможности Next.js 15
1. Молниеносная разработка с Turbopack
Сравнение производительности:
// package.json
{
"scripts": {
"dev": "next dev --turbopack",
"build": "next build --turbopack"
}
}2. Прирост производительности с серверными компонентами
Преимущества:
// app/products/[id]/page.tsx
async function ProductPage({ params }: { params: { id: string } }) {
// Получение данных на стороне сервера
const product = await fetchProduct(params.id);
return (
<div>
<ProductInfo product={product} />
{/* Клиентский компонент для интерактивности */}
<AddToCartButton productId={product.id} />
</div>
);
}3. Постепенный рендеринг с потоковым SSR
Пользовательский опыт:
import { Suspense } from 'react';
export default function ProductList() {
return (
<div>
<Suspense fallback={<ProductsSkeleton />}>
<Products />
</Suspense>
<Suspense fallback={<ReviewsSkeleton />}>
<Reviews />
</Suspense>
</div>
);
}4. Оптимизация изображений 2.0
Компонент Image в Next.js:
import Image from 'next/image';
<Image
src="/products/product-1.jpg"
alt="Название товара"
width={800}
height={600}
quality={85}
loading="lazy"
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
/>Результат: размер файла меньше на 60%, загрузка быстрее на 40%
SEO-оптимизация для электронной коммерции
1. Метаданные и Open Graph
// app/products/[slug]/page.tsx
import type { Metadata } from 'next';
export async function generateMetadata(
{ params }: { params: { slug: string } }
): Promise<Metadata> {
const product = await fetchProduct(params.slug);
return {
title: `${product.name} - лучшая цена | Название магазина`,
description: product.description,
openGraph: {
title: product.name,
description: product.description,
images: [product.image],
type: 'product',
},
twitter: {
card: 'summary_large_image',
title: product.name,
description: product.description,
images: [product.image],
},
};
}2. Структурированные данные (JSON-LD)
Расширенные сниппеты для Google:
export default function ProductPage({ product }) {
const structuredData = {
"@context": "https://schema.org",
"@type": "Product",
"name": product.name,
"image": product.image,
"description": product.description,
"sku": product.sku,
"offers": {
"@type": "Offer",
"price": product.price,
"priceCurrency": "TRY",
"availability": "https://schema.org/InStock",
"seller": {
"@type": "Organization",
"name": "Название магазина"
}
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": product.rating,
"reviewCount": product.reviewCount
}
};
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
/>
{/* Контент товара */}
</>
);
}3. Динамическая генерация sitemap
// app/sitemap.ts
import { MetadataRoute } from 'next';
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const products = await fetchAllProducts();
const productUrls = products.map((product) => ({
url: `https://example.com/products/${product.slug}`,
lastModified: product.updatedAt,
changeFrequency: 'weekly' as const,
priority: 0.8,
}));
return [
{
url: 'https://example.com',
lastModified: new Date(),
changeFrequency: 'daily',
priority: 1,
},
...productUrls,
];
}Оптимизация производительности
1. Оптимизация запросов к базе данных
Эффективные запросы с Prisma:
// lib/db/products.ts
import { prisma } from '@/lib/prisma';
export async function getProductWithRelations(slug: string) {
return await prisma.product.findUnique({
where: { slug },
include: {
category: true,
images: true,
reviews: {
take: 10,
orderBy: { createdAt: 'desc' },
include: { user: true }
},
variants: true,
},
});
}2. Стратегия кэширования в Redis
import { Redis } from '@upstash/redis';
const redis = new Redis({
url: process.env.UPSTASH_REDIS_URL,
token: process.env.UPSTASH_REDIS_TOKEN,
});
export async function getCachedProduct(id: string) {
// Сначала проверяем кэш
const cached = await redis.get(`product:${id}`);
if (cached) return cached;
// Получаем из базы данных
const product = await fetchProduct(id);
// Кэшируем на 1 час
await redis.setex(`product:${id}`, 3600, JSON.stringify(product));
return product;
}3. CDN и edge-функции
Edge Functions от Vercel:
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const country = request.geo?.country || 'US';
// Перенаправление в зависимости от страны
if (country === 'TR' && !request.nextUrl.pathname.startsWith('/tr')) {
return NextResponse.redirect(new URL('/tr', request.url));
}
return NextResponse.next();
}Оптимизация конверсии (CRO)
1. A/B-тестирование через middleware
export function middleware(request: NextRequest) {
const bucket = Math.random() < 0.5 ? 'a' : 'b';
const response = NextResponse.next();
response.cookies.set('bucket', bucket);
return response;
}2. Интеграция аналитики
Google Analytics 4:
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html>
<head>
<Script
src={`https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX`}
strategy="afterInteractive"
/>
<Script id="google-analytics" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
`}
</Script>
</head>
<body>{children}</body>
</html>
);
}Метрики успеха
Результаты на реальных проектах:
Решения для электронной коммерции от Enextware
Создайте свой интернет-магазин на Next.js 15 вместе с нами:
Бесплатная консультация: +90 536 628 0007
