Currently Available: Need a skilled Software Developer for your next project?
Categories
APIs

How to Deliver Headless CMS Content Through APIs

A headless content management system (CMS) stores content separately from the website or app that displays it. The website or app, called the frontend, retrieves that content through an application programming interface (API), which lets software request and exchange data. The way you connect the CMS and frontend determines when the frontend fetches content, how it protects unpublished material, and how quickly published changes reach readers.

Choose how to connect the CMS and frontend based on three needs. Decide how fresh the content must be and how much traffic the delivery path must handle. Also consider how the service should recover when a request or refresh fails. REST and GraphQL define how the frontend requests data. Build-time fetching gets content before pages are published, request-time fetching gets it while a page is served, and caching stores responses for reuse. These choices address different needs and do not replace one another.

Separate published content, drafts, and edits

Most headless CMS integrations have distinct paths for reading published content, previewing drafts, and changing content. A delivery API provides a website with published content, while editors or reviewers use a preview API to access unpublished versions. Authorized clients use a management API to change content. Contentful’s API overview documents these roles separately.

Keep each path’s credentials with the server-side code that needs them. Public pages should use a read-only delivery credential when the CMS provides one. Management credentials belong in trusted server code because they can grant write access. Preview credentials also need protection: draft content should not become accessible through a public page or a URL that exposes a token.

This separation gives each integration a clear purpose. A publishing event updates the delivery path; an editor preview request retrieves draft content; an authorized content-management tool makes changes through the management path.

Choose REST or GraphQL for the data request

REST organizes requests around resources, such as entries or assets, and typically uses a URL for each resource or collection. Choose REST when the CMS’s resource endpoints already match what the frontend needs. HTTP caching features can also help: Contentful documents ETag response headers and conditional requests using If-None-Match. When the response has not changed, the server can return 304 Not Modified, allowing the client to reuse its cached copy (Contentful HTTP details).

GraphQL lets a client request selected fields and related content in one query. That helps when a page needs a specific combination of data and would otherwise make several requests. But one GraphQL request does not guarantee one efficient operation behind the API. The service still needs to fetch its data, and large or repeated queries still need controls such as pagination, batching, and monitoring. The GraphQL performance guidance covers these concerns, while the GraphQL FAQ notes that GraphQL and REST can coexist.

Compare the actual query shapes, cache behavior, and CMS capabilities before choosing. A GraphQL query that returns the right fields can reduce client round trips, but it does not automatically reduce total backend work. REST can use HTTP caching effectively when the CMS and request design support it. Neither approach is inherently faster in every integration.

Decide when the frontend fetches content

A static site generator fetches content before publishing pages, then serves the rendered files to visitors. This avoids a CMS request for each page view, but content changes need a rebuild or another refresh mechanism. Request-time rendering fetches content while serving a page, which can show newer content without waiting for a full site rebuild, but it adds an upstream request to the page-serving path.

After publication, a CMS event can regenerate the page that displays the changed entry, so the hybrid approach refreshes selected pages while keeping the speed of pre-rendered pages. Choose this approach when a full rebuild takes too long or refreshes too much content, and the hosting platform supports targeted revalidation. Next.js documents a webhook-based revalidation pattern.

For frequently updated content, decide whether readers need to see the latest saved version, the latest published version, or an approved editorial version. That requirement determines whether a cached page is acceptable and what should trigger its refresh.

Add a server-side boundary where it helps

A backend-for-frontend (BFF) is a server-side layer between a specific frontend and the APIs it uses. Use a BFF when the frontend needs data from several services or a simpler response. It also fits when the server must keep credentials out of browser code. The BFF can retrieve CMS content, combine it with other data, and return a response for a specific page.

The BFF also adds code and another service to deploy, monitor, and troubleshoot. If a frontend can safely retrieve public content directly and does not need to combine or reshape data, an extra layer may add more work than value. Next.js’s BFF guidance shows one implementation option, not a requirement for every CMS-backed site.

Keep draft preview behind a protected server-side route or preview environment. That route can authenticate the editor, retrieve draft content with a preview credential, and return the preview without exposing the credential to the browser. Contentful documents a separate preview token and warns against putting an access token in a preview URL (Preview API overview).

Use webhooks to refresh changed content

A webhook is an HTTP notification that a CMS sends when an event occurs, such as publishing an entry. The receiving endpoint can use the event to trigger a site rebuild or page revalidation. It can also clear a cache or queue other work. Since a webhook reports an event rather than proving that a refresh finished, the receiver should acknowledge the notification quickly and handle the refresh separately.

Verify the sender’s signature when the CMS supports signatures, then check that the event applies to content your receiver handles. Make refresh jobs safe to repeat: CMS providers can send duplicate notifications, and a repeated event should not create incorrect results. Contentful documents signature verification and provider-specific delivery behavior. Under its documented default policy, qualifying 429 or 5xx responses receive up to two retries after the initial attempt; a request that times out after 30 seconds is treated as failed and is not retried. These rules are specific to Contentful. Check the chosen CMS’s timeout, retry, signature, and duplicate-delivery behavior before relying on it.

Set a cache policy readers can live with

A content delivery network (CDN) caches responses at servers closer to readers, reducing repeated requests to the CMS. Caching improves delivery only when the saved response is fresh enough for the page. Set how long the CDN keeps each kind of content and which event clears it from the cache. Also decide what readers see if a refresh fails.

Provider behavior varies. Sanity distinguishes its uncached API from its opt-in API CDN, with different guidance for frontend reads and integrations that need the latest saved content. Contentful documents configurable advanced caching, including options that can serve stale content during some rate-limit conditions. Those features depend on provider configuration and should not be assumed to exist in every CMS.

Check what forms the cache key. If locale, environment, query parameters, or authorization change the response, the cache must distinguish those requests. Also decide whether a stale page is preferable to an error while the CMS or refresh path is unavailable. The answer depends on the content: a slightly old article may be acceptable, while outdated pricing or availability may not be.

Match pagination to the amount of content

A listing page and a full content export have different pagination needs. Offset pagination asks for a starting position and page size, so it fits interfaces that let readers jump between pages. For a large export or index, follow the CMS’s cursor, which marks where the next page starts, or use its continuation links instead of repeatedly increasing an offset. Contentful describes offset pagination for bounded access and cursor pagination for traversing large collections in its delivery API documentation. Other CMS APIs may use different pagination rules.

Before launch, check the selected CMS’s request limits and whether they apply to cached reads, uncached reads, or both. For example, Contentful documents default limits of 55 uncached requests per second for its Content Delivery API and 14 requests per second for its Content Preview API; plan conditions can change those limits. These are product-specific figures, not general headless CMS thresholds. To stay within the provider’s limits, cache repeated reads and fetch only the content you need. For bulk jobs, follow the provider’s pagination guidance.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *