Skip to content

Complete internationalization (i18n) support for tina-cloud-starter using next-intl #606

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 32 commits into
base: main
Choose a base branch
from

Conversation

liawagner
Copy link

@liawagner liawagner commented Jun 9, 2025

Implemented comprehensive internationalization (i18n) support throughout tina-cloud-starter using next-intl. The site is fully functional and includes a language switcher for English and German.

We created this as an i18n proof of concept for our missions NGO website in the Philippines. This missions site is a side project of my daughter, who is currently studying Computer Science and has it live at: https://www.lightinasia.org/

The Tina Internationalized Starter Site can be accessed here: https://tina-cloud-starter-intl.vercel.app/

The main implementation steps, written in tutorial format, can be found in the README.md

I am submitting this as a PR, so you can easily see the file changes and added files, while hoping that official i18n support would be added to Tina CMS in the near future.

Maybe this could be also be added to the documentation which is currently lacking Next.js App Router based examples for i18n.

liawagner added 18 commits June 6, 2025 16:58
- Install next-intl
- Remove next.config import from tina/config.tsx to resolve import conflicts
- Hardcode basePath as empty string (was always defaulting to this anyway)
- Enable next-intl plugin wrapper in next.config.ts without compatibility issues
- Follow standard TinaCMS configuration patterns used in other projects
- Maintain separation of concerns between CMS and framework configurations
- Introduced middleware for handling internationalization using next-intl.
- Created routing configuration to define supported locales and default locale.
- Added navigation utilities to facilitate locale-aware navigation.
- Implemented request configuration to manage locale and message loading based on user requests.
…ell as not found page

- Updated RootLayout to validate incoming locale and handle not found cases.
- Enhanced NotFound component to utilize translations for dynamic content.
- Modified Home and Page components to support locale-specific content retrieval with fallback mechanisms.
- Integrated locale handling in URL segments to improve routing and content delivery.
…posts

- Add client-side filtering in app/[locale]/posts/page.tsx to filter posts by locale.
- Filter posts where _sys.relativePath starts with current locale (en/ or de/).
- Update totalCount to reflect filtered post count for accurate pagination.
- Remove posts from other locales from being displayed on locale-specific pages.
- Improves user experience by showing only relevant locale-specific content.
- Add server-side filtering in posts page to show only locale-specific content
- Filter posts by checking first breadcrumb segment against current locale
- Update individual post page to handle locale parameter properly
- Maintain existing data structure and type safety
…verLocaleFilter

feat: implement server-side locale filtering for blog posts and fix individual post page to handle locale parameter properly
- Wrapped Tina client.queries.post() call in try-catch block in posts/[...urlSegments]/page.tsx
- Call notFound() when post doesn't exist instead of throwing unhandled error
- Follow same error handling pattern used in other page components
- Ensures unknown post URLs show proper 404 page instead of crashing application
…items sourced from global/index.json

- Import getLocale from next-intl/server to detect current locale
- Implement try-catch pattern to load locale-specific global content first
- Add fallback to non-locale specific content for backward compatibility
- Follow same pattern as page.tsx for consistency
- Resolves "Unable to find record content/global/index.json" error
- Eliminated console log statements for locale-specific home and fallback content in app/[locale]/page.tsx.
- Removed unnecessary check for blog posts route in app/[locale]/[...urlSegments]/page.tsx to streamline routing logic.
- Move navigation from right to left (next to logo)
- Move site name to far right position
- Add language switcher with flag icons (🇩🇪/🇺🇸) before site name
- Implement responsive mobile menu with nav items first
- Place language switcher and site name at bottom of mobile menu
- Maintain existing design system styling and hover states
- Integrate with existing next-intl setup
- Added internationalization support for the introduction section in client-page.tsx, which lists the blog posts.
- Implemented useTranslations hook to fetch localized titles and descriptions.
- Updated German and English translation files with corresponding content for PostsList.
- Translated various sections of the home page to German, including callouts, headlines, descriptions, and testimonials.
Copy link

vercel bot commented Jun 9, 2025

@liawagner is attempting to deploy a commit to the TinaCMS Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant
Copy link

CLAassistant commented Jun 9, 2025

CLA assistant check
All committers have signed the CLA.

- Bump project version from 0.1.0 to 0.3.0
- Upgrade various dependencies
- Adjust peer dependency rules in pnpm-workspace.yaml for React and related packages
- Update README with instructions for dependency management and version checks
…s after React 19 and related upgrades

- Add proper TypeScript type annotations for motion variants
- Use 'as const' assertion for spring transition type
- Import Variants type from motion/react for proper typing
- Ensure compatibility with React 19 and TypeScript 5.8.3

This resolves the "Type 'string' is not assignable to type
'AnimationGeneratorType'" error by properly typing motion variants.
- Create ImageContent component with responsive grid layout
- Add imageContentBlockSchema with image and rich-text fields
- Register block in components/blocks/index.tsx and page collection
- Implement proper TinaCMS live editing annotations
- Use Next.js Image optimization and accessibility features
- Add imagePosition dropdown field with Left/Right options
- Implement conditional CSS grid ordering based on selection
- Position selector below Background field in CMS interface
- Upgrade various packages including framer-motion, postcss, and typescript-related types.
…/AddBlocks

feat: add image content block with image and markdown layout side-by-side
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants