To integrate Kentico with V0 by Vercel, use the Kentico Delivery API (for Kontent.ai) or the Xperience by Kentico Content API to fetch content from a Next.js API route. V0 generates the frontend UI; the API route retrieves structured content items using your Delivery API key stored in Vercel environment variables for a fully headless CMS deployment.
Build an Enterprise Headless CMS Frontend with Kentico and V0
Kentico is a leading enterprise CMS used by major brands and government organizations. The modern Kentico product line includes Kontent.ai (formerly Kentico Kontent) — a cloud-native, API-first headless CMS — and Xperience by Kentico — an on-premise or cloud DXP with headless capabilities. Both products expose REST APIs for content delivery, making them excellent backends for V0-generated Next.js frontends.
Kontent.ai's Delivery API is purpose-built for headless scenarios. Content is modeled as structured content items with typed elements (text, rich text, number, date-time, asset, linked items, taxonomy). The Delivery API provides a powerful filtering and querying system that supports sorting, pagination, depth control for linked items, and taxonomy filtering. For V0 developers, this means you can fetch exactly the fields you need for each component without over-fetching.
This guide covers the Kontent.ai integration pattern, which is applicable to both Kontent.ai and Xperience by Kentico headless APIs. The integration uses the official @kontent-ai/delivery-sdk TypeScript package, which provides type-safe content item access and reduces boilerplate compared to raw REST calls.
Integration method
V0 generates the Next.js frontend for rendering Kentico/Kontent.ai content. A Next.js API route calls the Kontent.ai Delivery API using your environment ID and Delivery API key stored as Vercel environment variables. Content items, their elements, and linked items are fetched server-side and returned to the frontend as clean TypeScript objects.
Prerequisites
- A Kontent.ai account (free trial available at kontent.ai) with at least one environment and content model set up
- At least one content type defined in Kontent.ai with some published content items
- Your Kontent.ai Environment ID and Delivery API key from the Project Settings
- A V0 account at v0.dev and a Vercel account for deployment
- Basic understanding of headless CMS concepts (content types, content items, content elements)
Step-by-step guide
Set Up Kontent.ai Delivery API Access
Set Up Kontent.ai Delivery API Access
Log in to your Kontent.ai environment at app.kontent.ai. Navigate to your project's Settings → API keys in the left sidebar. You will see the Delivery API section with two key types: the Production Delivery API key (for published content) and the Preview Delivery API key (for unpublished draft content). For the initial integration, use the Production Delivery API key. Also copy your Environment ID from the same page — it is a UUID format string. Your Delivery API key is a long JWT-like string. For a read-only V0 integration (fetching and displaying content), only the Delivery API key and Environment ID are needed — you do not need the Management API key, which is used for content creation and modification. If your content model uses linked items (e.g., a page that has linked article items), also note the content type codenames — you will use these to filter API responses. Kontent.ai's Delivery API base URL is https://deliver.kontent.ai/{environment-id}/items for fetching content items.
Pro tip: Kontent.ai offers a free trial with a sample project populated with realistic content. Use the sample project to test your integration before connecting to your real content — it saves time setting up test content.
Expected result: You have your Kontent.ai Environment ID and Delivery API key copied and ready as environment variable values.
Install the Kontent.ai Delivery SDK
Install the Kontent.ai Delivery SDK
The official Kontent.ai Delivery SDK (@kontent-ai/delivery-sdk) provides a TypeScript-first client for the Delivery API with type-safe content item access, automatic response parsing, and built-in retry logic. Install it in your V0-exported project. If you are working directly in V0's code editor, add it to package.json manually. The SDK client is initialized with your environment ID and API key. For SSR and serverless environments (like Vercel), create the client inside the API route handler rather than as a module-level singleton — this prevents credential leakage between requests in edge cases. Alternatively, the createDeliveryClient function is safe to call at module level since it only stores the configuration, not authentication state. The SDK supports rich text HTML rendering, linked item resolution, and asset URL generation — features that would require significant custom code if using the raw REST API.
1// Install the Kontent.ai Delivery SDK2// In your project terminal or package.json:3// npm install @kontent-ai/delivery-sdk45// app/lib/kontent.ts — shared client configuration6import { createDeliveryClient } from '@kontent-ai/delivery-sdk';78export const deliveryClient = createDeliveryClient({9 environmentId: process.env.KONTENT_ENVIRONMENT_ID!,10 deliveryApiKey: process.env.KONTENT_DELIVERY_API_KEY,11 // Use preview key for draft content:12 // previewApiKey: process.env.KONTENT_PREVIEW_API_KEY,13 // defaultQueryConfig: { usePreviewMode: false },14});Pro tip: Add both the Delivery API key and Preview API key as environment variables even if you only use the production key now. This makes it easy to add a preview mode feature later without reconfiguring your setup.
Expected result: The @kontent-ai/delivery-sdk package is installed. The shared client module is created with environment variable references.
Generate the Content Website UI with V0
Generate the Content Website UI with V0
Open V0 at v0.dev and describe the content pages you want to build. V0 generates excellent content layouts — magazine-style homepages, structured article pages, product catalogs, and documentation layouts. When describing the data shape to V0, use Kontent.ai's terminology: content items have a system object (codename, name, type) and an elements object with named element fields. For a typical article, elements include a title text element, body rich text element, hero image asset element, and taxonomy elements for categories and tags. Describe these fields to V0 so it generates components that map cleanly to Kontent.ai's response structure. Ask V0 to fetch from /api/kentico/content so the component is ready for the API route you will create next. Use V0's Design Mode to tweak typography — rich text content especially benefits from good heading hierarchy and line spacing. Deploy once the layout looks right.
Create a content article listing page with a page header showing the category name and article count. Below, show a masonry-style grid of article cards with: featured image, category tag, article title, publication date, author name, and a 2-line excerpt. Clicking a card links to /articles/[slug]. Fetch articles from /api/kentico/articles?limit=12. Show a loading skeleton grid while fetching.
Paste this in V0 chat
Pro tip: Ask V0 to generate an ArticleCard component and an ArticleGrid component separately — this component separation makes it easier to reuse the card in other page contexts.
Expected result: V0 generates an article listing page with a card grid. The components are ready to receive Kontent.ai content item data.
Create the Kontent.ai Content API Route
Create the Kontent.ai Content API Route
Create the Next.js API route that uses the Delivery SDK to fetch content from Kontent.ai. The SDK provides a fluent API for querying content items by type, filtering, sorting, and depth. For fetching articles, use client.items().type('article').toPromise() — where 'article' is your content type codename in Kontent.ai. The response contains an items array of typed content item objects. Each item has an elements property with the content fields. Access elements like item.elements.title.value (text), item.elements.body.value (HTML string for rich text), item.elements.hero_image.value[0].url (asset URL). For single item fetch by URL slug, use client.items().type('article').equalsFilter('elements.url_slug', slug).toPromise(). The 'url_slug' must match the exact codename of the URL slug element in your content model. The SDK handles authentication, retry logic, and response parsing automatically.
1import { NextResponse } from 'next/server';2import { deliveryClient } from '@/app/lib/kontent';34export async function GET(request: Request) {5 const { searchParams } = new URL(request.url);6 const limit = parseInt(searchParams.get('limit') ?? '10', 10);7 const contentType = searchParams.get('type') ?? 'article';8 const slug = searchParams.get('slug') ?? '';9 const language = searchParams.get('language') ?? '';1011 try {12 let query = deliveryClient13 .items()14 .type(contentType)15 .limitParameter(limit)16 .orderByDescending('system.last_modified');1718 if (slug) {19 query = deliveryClient20 .items()21 .type(contentType)22 .equalsFilter('elements.url_slug', slug);23 }2425 if (language) {26 query = query.languageParameter(language);27 }2829 const response = await query.toPromise();3031 const items = response.data.items.map((item) => ({32 id: item.system.id,33 codename: item.system.codename,34 name: item.system.name,35 type: item.system.type,36 lastModified: item.system.lastModified,37 language: item.system.language,38 elements: Object.fromEntries(39 Object.entries(item.elements).map(([key, el]) => [40 key,41 (el as { value: unknown }).value,42 ])43 ),44 }));4546 return NextResponse.json({ items, total: items.length });47 } catch (error) {48 console.error('Kontent.ai API error:', error);49 return NextResponse.json({ error: 'Failed to fetch content' }, { status: 500 });50 }51}Pro tip: Add the depth parameter (.depthParameter(2)) to your query when content types use linked items — this resolves one level of linked content in the same API call, avoiding N+1 fetch patterns.
Expected result: GET /api/kentico/articles returns a JSON array of content items with their elements. The article title, body, and image data are present in the response.
Add Environment Variables and Configure ISR
Add Environment Variables and Configure ISR
Navigate to your Vercel project, go to Settings → Environment Variables, and add KONTENT_ENVIRONMENT_ID (the UUID from Kontent.ai Project Settings) and KONTENT_DELIVERY_API_KEY (the Delivery API key). Neither variable needs the NEXT_PUBLIC_ prefix since they are server-side only. Also add KONTENT_PREVIEW_API_KEY for the Preview environment scope if you want to support draft content preview. After adding variables, redeploy. To optimize performance, configure Incremental Static Regeneration (ISR) for content pages. In your Next.js page component, export a revalidate constant to tell Vercel how often to regenerate the page: export const revalidate = 300 for 5-minute cache. For article listing pages, 60-300 seconds is appropriate; for article detail pages that change rarely, 3600 seconds (1 hour) is better. Kontent.ai also supports webhooks for on-demand ISR — when an editor publishes a change, Kontent.ai sends a webhook to your Vercel deployment URL to trigger immediate page regeneration. Set the webhook URL to https://your-vercel-app.vercel.app/api/revalidate and pass a secret token to validate the request. For enterprise content teams requiring custom preview workflows and on-demand revalidation, RapidDev can help implement the full webhook-based ISR pipeline.
1// app/articles/page.tsx — enable ISR caching2export const revalidate = 300; // Regenerate every 5 minutes34export default async function ArticlesPage() {5 const res = await fetch(`${process.env.NEXT_PUBLIC_APP_URL}/api/kentico/articles?limit=12`);6 const { items } = await res.json();7 return <ArticleGrid articles={items} />;8}910// Alternatively, call Kontent.ai directly in a Server Component:11import { deliveryClient } from '@/app/lib/kontent';1213export default async function ArticlesPage() {14 const response = await deliveryClient.items().type('article').limitParameter(12).toPromise();15 return <ArticleGrid articles={response.data.items} />;16}Pro tip: For article detail pages with static generation, use generateStaticParams to pre-render all article pages at build time: fetch all article codenames and slugs from Kontent.ai and return them as params.
Expected result: Environment variables are configured. Content pages render with real Kontent.ai data and ISR caching is active. Page regeneration respects the revalidate interval.
Common use cases
Enterprise Website CMS
Build a marketing website where enterprise content teams manage pages, press releases, and product content in Kontent.ai's structured editor while the V0-generated Next.js frontend renders them with custom design and performance optimization.
Create a corporate website homepage with a hero section (headline, subheadline, CTA button), a features grid showing 3 feature cards (icon, title, description), and a news section with the latest 3 articles. Fetch the homepage content from /api/kentico/pages?slug=home and articles from /api/kentico/articles?limit=3.
Copy this prompt to try it in V0
Multilingual Content Hub
Kontent.ai has first-class multilingual support with language variants. Build a content hub that serves translated content to international audiences, with the API route passing the language parameter to the Delivery API.
Design a knowledge base with a language selector in the header, a sidebar with topic categories, and a main content area showing the article title and rich text body. The language selector should update a URL param and refetch content from /api/kentico/articles?slug=article-slug&language=es-ES.
Copy this prompt to try it in V0
Product Catalog with Rich Content
Use Kontent.ai's structured content models to manage product descriptions, specifications, and media assets, with V0 generating the product listing and detail pages that render this content with e-commerce-quality presentation.
Create a product detail page with a left image gallery (main image + thumbnails), a right panel with product name, description text, a specs table, and an 'Add to Cart' button. Fetch product data from /api/kentico/products?codename=product-codename and render the rich text description.
Copy this prompt to try it in V0
Troubleshooting
DeliveryError: Requested response returned 401 — unauthorized
Cause: The KONTENT_ENVIRONMENT_ID or KONTENT_DELIVERY_API_KEY is incorrect, or the API key has been regenerated in Kontent.ai settings.
Solution: In Kontent.ai → Project Settings → API keys, verify the Environment ID (UUID) and Delivery API key match KONTENT_ENVIRONMENT_ID and KONTENT_DELIVERY_API_KEY in Vercel exactly. Regenerate the key if needed and update Vercel, then redeploy.
Content items return but elements object is empty or missing expected fields
Cause: The element codenames in your code do not match the actual codenames in the Kontent.ai content type. Element codenames are auto-generated from the element name and may contain underscores.
Solution: In Kontent.ai, open the content type in the Content Modeling section and click on each element to see its exact codename (shown below the element name). Use these exact codenames when accessing item.elements.your_codename.
Rich text elements return HTML with broken images or missing linked content
Cause: Rich text HTML from Kontent.ai contains Kontent.ai-specific data attributes for inline linked items and assets that need to be resolved before rendering.
Solution: Use the Kontent.ai Rich Text Resolver or implement a custom resolver to transform the raw rich text HTML into properly rendered HTML before passing it to dangerouslySetInnerHTML. The SDK's .richTextResolverConfig() method handles inline linked item resolution.
Content items for correct type return 0 items despite items existing in Kontent.ai
Cause: The content type codename passed to the query does not match the actual type codename, or the items are not published (in draft state).
Solution: In Kontent.ai, open your content type and check the codename shown at the top of the page (not the display name). The codename is lowercase with underscores. Ensure items are 'Published' not 'Draft' — the Delivery API only returns published items unless using the Preview API.
Best practices
- Use the official @kontent-ai/delivery-sdk instead of raw fetch calls — it handles authentication, retries, and type safety automatically
- Configure ISR with revalidate settings appropriate for your content update frequency — news sites may need 60 seconds, corporate pages can use 3600 seconds
- Set up Kontent.ai webhooks pointing to a /api/revalidate route for on-demand ISR when editors publish changes
- Store only the Environment ID and Delivery API key — never the Management API key — in frontend-accessible configuration
- Use the depth parameter when fetching content with linked items to avoid N+1 API call patterns
- Generate TypeScript interfaces from your Kontent.ai content types using the @kontent-ai/model-generator CLI tool for type-safe element access
- Cache taxonomy terms and content type lists separately with longer revalidation intervals since they change less frequently than content items
Alternatives
TYPO3 is a comparable enterprise PHP CMS with headless capabilities, preferred in German-speaking European markets while Kentico is popular in the US and UK enterprise markets.
WordPress has a much larger developer ecosystem and more hosting options, making it a simpler choice for teams without enterprise CMS experience.
Joomla is open-source and free to self-host, while Kentico/Kontent.ai requires paid licensing — Joomla is better for cost-sensitive projects needing a headless API.
Ghost is purpose-built for publishing with a cleaner API, making it easier to integrate for blog and newsletter use cases compared to Kentico's enterprise-focused API.
Frequently asked questions
What is the difference between Kontent.ai and Xperience by Kentico?
Kontent.ai is Kentico's cloud-native headless CMS — a pure API-first product with no rendering engine. Xperience by Kentico is a full Digital Experience Platform (DXP) that supports both traditional on-page rendering and headless API delivery. For V0 headless integrations, Kontent.ai's Delivery API is cleaner and more straightforward. Xperience by Kentico has its own Content API for headless use cases.
Does Kontent.ai have a free tier?
Kontent.ai offers a free Starter plan with 3 user seats, 1,000 content items, 3 content types, and 2 languages. This is sufficient for development and small projects. Paid plans start at around $799/month for the Business tier with additional seats, items, and features.
How do I implement content preview for draft articles?
Kontent.ai provides a separate Preview Delivery API key for accessing draft content. In your Next.js app, check for a preview cookie or a is_preview query parameter, and if present, initialize the delivery client with the Preview API key and usePreviewMode: true. This allows editors to see unpublished content before publishing through a preview URL.
Can I use Kontent.ai's Delivery API in Next.js Server Components directly?
Yes. You can call the Kontent.ai Delivery SDK directly in async Server Components without going through an API route. Import the deliveryClient in your page.tsx or layout.tsx and call await deliveryClient.items().type('article').toPromise() directly. This is often simpler than creating an API route layer for internal Next.js data fetching.
How do I handle Kontent.ai's taxonomy terms for filtering?
Taxonomy elements in Kontent.ai return an array of term codenames. Use the containsFilter() or anyFilter() methods in the Delivery SDK to filter by taxonomy: query.containsFilter('elements.categories', ['news', 'technology']). Fetch the full taxonomy term tree from the /taxonomies endpoint to build category navigation.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation