This React Router v7 application uses server-side loaders for data fetching rather than traditional REST APIs. All data loading happens during server-side rendering with caching optimization.
GET /blog - Blog listing page
- Loader:
createHybridLoaderwith cache strategy - Data Source: Content API (GitHub/filesystem)
- Query Parameters:
tag(optional): Filter posts by tagrefresh=1(optional): Bypass cache
- Response:
{ posts: BlogPost[], isError: boolean } - Cache Strategy:
blogPost(1 hour fresh, 24 hours stale-while-revalidate)
GET /blog/$slug - Individual blog post
- Loader: Content fetching with error handling
- Parameters:
slug- Post identifier - Response:
{ post: BlogPost }or 404 - Cache Strategy:
blogPost
GET /clients - Client stories listing
- Loader: Content fetching with sorting
- Response:
{ stories: Story[] } - Cache Strategy:
story
GET /clients/$slug - Individual client story
- Loader: Content fetching with metadata
- Parameters:
slug- Story identifier - Response:
{ story: Story }or 404 - Cache Strategy:
story
GET /contact - Contact page
- Loader: i18n data preparation
- Response:
{ title: string, description: string, ogImageSrc: string } - Features:
- Contact form processing (HubSpot integration)
- Language-aware meta tags
- OG image generation
GET /projets-revops - RevOps projects page (French)
GET /strategies-revenue-operations - Revenue operations page (French)
- Loader: i18n meta preparation
- Features:
- Language routing with
($lang)parameter - Automatic locale redirect
- SEO optimization
- Language routing with
GET /sitemap.xml - Dynamic sitemap generation
- Loader: Aggregates all content for sitemap
- Data Sources:
- Blog posts (with dates)
- Client stories (with dates)
- Static pages
- Output: XML sitemap format
- Headers:
Content-Type: application/xml
GET /robots.txt - Robots.txt file
- Static: Robot crawling instructions
- Headers:
Content-Type: text/plain
Base URL: https://api.github.com/repos/{account}/{repo}/contents
Authentication: GitHub Access Token (Bearer)
GET /contents/blog - Fetch blog posts
- Headers:
Authorization: Bearer {token} - Query:
?ref={branch}(branch targeting) - Response: GitHub file tree with content
GET /contents/stories - Fetch client stories
- Headers:
Authorization: Bearer {token} - Query:
?ref={branch} - Response: GitHub file tree with content
Local Path: ~/projects/ocobo-posts/
- blog/: Markdown blog posts
- stories/: Client story markdown files
- No Authentication: Direct file system access
interface BlogPost {
slug: string;
frontmatter: {
title: string;
date: string;
description: string;
tags: string[];
author?: string;
image?: string;
};
content: string;
readingTime?: number;
}interface Story {
slug: string;
frontmatter: {
title: string;
date: string;
client: string;
sector: string;
description: string;
deliverables: string[];
results: string[];
image?: string;
};
content: string;
}- 200: Successful data fetch
- 404: Content not found (post/story doesn't exist)
- 500: Server error (GitHub API failure, file system error)
// Graceful degradation
{ posts: [], isError: true } // Blog listing error
{ stories: [], isError: true } // Stories listing error
// 404 handling
throw new Response('Not Found', { status: 404 });Cache-Control: s-maxage=3600, stale-while-revalidate=86400
Vary: Accept-Language- blogPost: 1 hour fresh, 24 hours stale-while-revalidate
- story: 1 hour fresh, 24 hours stale-while-revalidate
- static: 24 hours fresh, 7 days stale-while-revalidate
- URL Parameter:
?refresh=1 - Development: No caching with
CONTENT_SOURCE=locale
- URL Parameter:
($lang)optional parameter - Supported Languages:
fr(default),en - Fallback: French for missing translations
/ → French homepage
/en/ → English homepage
/contact → French contact
/en/contact → English contact
- Endpoint: Custom HubSpot integration
- Method: POST form submissions
- Validation: Server-side form processing
- Integration:
@vercel/analyticsand@vercel/speed-insights - Data Collection: Page views, performance metrics
- Privacy: GDPR compliant
- CORS: Configured for content domains
- CSP: Content Security Policy for external resources
- Bot Detection:
isbotlibrary for analytics filtering
- Edge Caching: Global CDN distribution
- Bundle Splitting: Route-based code splitting
- Image Optimization: Lazy loading and optimization
- Critical CSS: Above-the-fold CSS inlining
This API architecture prioritizes performance and SEO through server-side rendering while maintaining developer experience through TypeScript and modern React patterns.