CinemAmbiente Media is a full-stack web application built with Remix.js v2.9 (Vite-based) and React 18, serving as the digital platform for the CinemAmbiente environmental film festival. The project leverages DatoCMS as its headless CMS through a deep, multi-layered integration.
Content is fetched via DatoCMS's GraphQL Content Delivery API using a lightweight custom client (tiny-json-http) with support for environment-based endpoints and preview mode (toggled via cookie-based sessions). A secondary integration uses the DatoCMS Content Management API (@datocms/cma-client-node) for server-side write operations, such as user management. GraphQL queries and fragments are co-located in dedicated .graphql files, with full type generation powered by graphql-codegen producing typed document nodes and TypeScript operations from the DatoCMS schema.
The architecture implements a build-time data pre-fetching strategy: init scripts paginate through DatoCMS to generate static JSON files for movies, directors, and topics across both locales, enabling fast client-side filtering and search (powered by Fuse.js) without runtime API calls for listing pages. Dynamic detail pages query DatoCMS at request time through Remix loaders. DatoCMS webhooks are consumed via dedicated API routes to trigger transactional emails through Brevo on content events (e.g., form submissions, new user registrations).
Internationalization (Italian/English) is handled with remix-i18next and react-i18next, with a custom routing layer that programmatically duplicates all routes under an /en prefix via Vite config, sharing the same page components across both locales. DatoCMS content is fetched locale-aware using the SiteLocale scalar.
Authentication is managed by Clerk (@clerk/remix), integrated with DatoCMS user records to gate access to a dashboard area featuring collections, contests, educational dossiers, role-playing activities, and storytelling modules. The UI is built with Tailwind CSS, Framer Motion for animations, Headless UI for accessible components, Swiper for carousels, PhotoSwipe for gallery lightboxes, and ReactPlayer for video embedding. The component library follows an atomic design structure (Atoms → Molecules → Organisms → Sections → Pages) and is documented in Storybook 8.
The project includes a comprehensive DX setup with TypeScript, Vitest for unit testing, Cypress for E2E, ESLint + Prettier with Husky pre-commit hooks, and lint-staged for incremental formatting.