Skip to content

Saile

A bilingual personal site built as a product: portfolio, CV, dynamic content and discovery tools, in an accessible, self-hosted application.

Since 2023Personal projectIn production
Next.jsReactTypeScriptTailwind CSSnext-intlSerwistMiniSearchGitHub ActionsPM2

Context

I launched Saile in 2023 to present my background, skills and projects. The site evolved with my profile. From a portfolio focused on development, it became a personal product I design, build, deploy and maintain end to end.

The challenge is combining professional and personal content without losing the clarity a portfolio needs. A visitor checking my CV should find the information right away. A visitor who wants to explore can browse case studies, music, films and the site's technical choices.

The product today

Saile brings several uses together in one consistent application.

  • A portfolio available in French and English, with a profile, case studies and a contact form.
  • A CV available on the web and generated on demand as a one-page A4 PDF, adapted to each language.
  • A music page powered by the Spotify API: current track, most-listened tracks and artists, three selected playlists.
  • A film and series library built on TMDB, with filters, sorting, search, detail pages and recommendations sent to Discord.
  • A command palette accessible via Cmd or Ctrl + K, searching pages, projects, commands and the TMDB catalogue.
  • QR codes, social metadata and structured data to make content easier to share and discover.

Architecture and data

The application runs on the Next.js 16 App Router, React 19 and TypeScript. Pages use server rendering and static generation whenever possible. Pages linked to Spotify and TMDB regenerate periodically. API routes keep external calls and their secrets away from the browser.

  • next-intl centralises French and English content, localised routes and their metadata.
  • Projects are described in a shared structured source, used by the grid, detail pages, navigation, sitemap and search.
  • Full-text search indexes are generated at build time, then loaded with MiniSearch only when the command palette opens for the first time.
  • The Spotify and TMDB integrations include fallback states: an external outage must not block the rest of the site.
  • Serwist handles the PWA manifest, service worker and caching strategies, with specific handling for data that must never serve stale.

Design and accessibility

The design stays personal without getting in the way of the content. The interface relies on reusable components, a stable typographic hierarchy and colours defined by role rather than hardcoded in components.

  • Three themes: light, dark and high contrast.
  • Visitors can switch to Atkinson Hyperlegible, increase text size and disable animations.
  • Keyboard navigation, skip links, focus indicators, native dialogs and accessible labels are treated as product features.
  • Responsive images, deferred imports and lazy loading of third-party services keep each page's initial cost low.

Quality, search visibility and security

Site quality is checked like a production application. Every pull request runs linting, TypeScript checks, the production build and Lighthouse CI under mobile emulation. The configuration requires an accessibility score of 100 and at least 90 for performance, best practices and SEO.

Each language has its own metadata, hreflang links and sitemap entries. Main pages also publish WebSite, Person or CreativeWork structured data. On security, the server applies a Content Security Policy, HSTS, embedding restrictions and a permissions policy. API tokens and webhooks stay server-side only.

Deployment and operations

The main branch deploys automatically through GitHub Actions. The workflow connects to the VPS, syncs the repository, installs dependencies with npm ci, builds the Next.js app and restarts it with PM2. Nginx serves as the entry point and Uptime Kuma monitors service availability.

This delivery chain covers the full product lifecycle: content updates, development, testing, publishing, monitoring and maintenance of external integrations.

Outcome

Saile is both my public website and my experimentation ground. Evolving it since 2023 taught me how to maintain a product over time, revisit decisions that became limiting and balance functional richness, simplicity, performance and accessibility.

The project evolves with my career. Every new feature must fit the existing system, stay usable in both languages and avoid degrading the experience of visitors who came for one piece of information.

Back to projects