$ show tinacms/tina.io
This repository powers the tina.io website: a marketing, blog, changelog, and documentation hub for TinaCMS (an open-source Git-backed headless CMS). Built with Next.js 14 (App Router), TypeScript, Tailwind CSS, and TinaCMS itself as the content management system, it dogfoods the product. Content is stored as JSON (structured pages with block-based templates) and MDX (blog posts with rich components). The site features internationalization (English/Chinese with automated translation workflows), Algolia search indexing, API routes for Mailchimp, SendGrid, GitHub, and YouTube integrations, OG image generation via Satori/resvg, visual regression testing with Playwright, and a comprehensive UI component library. The architecture is a standard Next.js monolith with a block-based page builder and a custom TinaCMS schema defining 12 content collections. While the codebase is well-organized and actively maintained, it exhibits some technical debt: mixed styling systems (styled-components and Tailwind), TypeScript strict mode disabled, and a large block template set that may become unwieldy. The i18n implementation relies on duplicated route trees, which a design document aims to refactor.
The LLM identified 4 files worth highlighting for reuse:
Generates Open Graph images server-side using Satori and resvg. Provides pure functions to create SVG data URIs for backgrounds, truncate text to fit, compute font sizes based on string length, and assemble Facebook/Instagram sized images. Isolated from business logic, can be extracted into any Next.js project needing dynamic OG images with custom fonts and layouts.
A parameterized internationalization utility that maps locale keys to string objects. Exports a `getUiStrings` function and a `translate` helper that replaces `{{placeholder}}` patterns. Fully typed (generates union types from keys) and zero-dependency. Demonstrates a clean, testable pattern for adding i18n without heavy frameworks.
A self-contained carousel component built on the Embla library with autoplay, dots navigation, and infinite loop support. Receives `slides` as a ReactNode array and exposes options via a configuration object. No external styled-components or Tailwind coupling; styles are inline and can be overridden. Ready for extraction into any React project needing a lightweight carousel.
A lightweight YouTube embed component using the `lite-youtube-embed` web component under the hood. Renders a placeholder thumbnail initially and loads the full player only on user interaction. Accepts `id`, `title`, and `params` props. Static, no runtime dependencies beyond the web component import. Excellent pattern for reducing page weight from video embeds.