Skip to Content

Feature: CMS

The webapp uses Contentstack as its headless CMS for blog posts and location content. There is also an embedded Sanity Studio at /studio (legacy), but active content is served from Contentstack.

Contentstack Client

Configured in src/lib/contentstack/client.ts:

import contentstack from "@contentstack/delivery-sdk"; const stack = contentstack.stack({ apiKey: process.env.CONTENTSTACK_API_KEY || "", deliveryToken: process.env.CONTENTSTACK_DELIVERY_TOKEN || "", environment: process.env.CONTENTSTACK_ENVIRONMENT || "production", host: "eu-cdn.contentstack.com", });

The client connects to the EU CDN (eu-cdn.contentstack.com).

Environment Variables

CONTENTSTACK_API_KEY= CONTENTSTACK_DELIVERY_TOKEN= CONTENTSTACK_ENVIRONMENT=production

Blog Posts

Blog pages live at src/app/[locale]/blog/:

  • page.tsx — Blog index with pagination
  • [slug]/page.tsx — Individual blog post

Content Type: blog_post

Posts are queried with:

const result = await stack .contentType("blog_post") .entry() .query() .orderByDescending("published_at") .find<Post>();

Each post has these fields:

FieldTypeDescription
uidstringContentstack unique ID
titlestringPost title
slugstringURL slug
excerptstring (optional)Short description
cover_imageContentstackAsset (optional)Hero image
published_atstring (optional)Publication date
region"us" | "uk" | "both" (optional)Region visibility

Region Filtering

Posts are filtered by locale on the server:

posts.filter( (p) => !p.region || p.region === "both" || p.region === locale, );

Posts without a region field or with region: "both" appear in both locales.

Caching

Blog pages set export const revalidate = 0 — they are not cached and always fetch fresh content.

Location Content

Location-specific content (university info, area descriptions) is managed through Contentstack via the location-content feature:

src/features/location-content/ api/ queries.ts # Contentstack queries for location data components/ location-template.tsx # Template for location pages university-cards.tsx # University info cards area-cards.tsx # Area info cards location-content-section.tsx

Sanity Studio (Legacy)

An embedded Sanity CMS Studio is available at /studio/[[...index]]. This appears to be a legacy integration. The route is a catch-all that serves the Sanity Studio UI.

Image Utilities

Contentstack image handling is available via src/lib/contentstack/image.ts, re-exported from the client module:

import { getImageUrl, type ContentstackAsset } from "@/lib/contentstack/client";
Last updated on