PublicPersonal Project

Ocean Keep Diving

Project Overview

After discussing the required pages, information architecture, and visual style with the client, I independently handled the entire website development process, including content organization, route planning, UI design, development, deployment, domain configuration, multilingual support, SEO optimization, and the integration of a content management system (CMS).

The website covers diving courses, instructor profiles, pricing information, event schedules, and contact details. It was designed with maintainability and long-term scalability in mind.

Live Site

Ocean Keep Diving

Tech Stack

Next.js, React, Tailwind CSS, DaisyUI, Sanity, next-intl, Docker, Nginx, DigitalOcean, Cloudflare

Content Management System (CMS) Selection

In addition to relatively static content, the client wanted a dedicated space where they could write and publish articles.

Although the original data structure was organized for easy maintenance and allowed content to be added or updated quickly, every change still required a developer to modify the code and redeploy the website. This would increase the ongoing maintenance cost over time.

For this reason, I decided to introduce a headless CMS. Unlike my personal website, which uses Strapi, I selected Sanity for this project. The decision was mainly based on infrastructure cost, while also giving me an opportunity to explore a different content management solution.

Sanity makes it straightforward to define custom schemas through configuration files and deploy Sanity Studio on its hosted platform. The client can create, edit, and publish documents directly through a browser-based interface, with the updated content then reflected on the website.

Sanity API queries use GROQ, or Graph-Relational Object Queries, a query language developed by Sanity. GROQ makes it possible to filter content by document type, field conditions, and sorting rules while returning only the fields required by the page.

Example:

const POSTS_QUERY = defineQuery(`*[
  _type == "post"
  && defined(slug.current)
]|order(publishedAt desc)[0...24]{
  _id,
  title,
  category,
  slug,
  publishedAt,
  excerpt,
  image
}`);

This query retrieves posts with a valid slug, sorts them by publication date in descending order, limits the result to 24 documents, and returns only the fields required by the article listing page.

Website Architecture

The website is built with Next.js, with routes organized around diving courses, instructors, the event calendar, articles, and other contents.

Shared interface sections are separated into reusable React components, while page content is managed through structured data. When adding similar pages or updating website information, existing components and data formats can be reused instead of rebuilding the same layouts.

Next.js also provides an integrated approach to routing, metadata management, and server-side data fetching. This allows each page to generate its own title, description, and URL information based on its content.

Multilingual Support

The website uses next-intl to provide Traditional Chinese, English, and Japanese versions, with locale-specific routes for each language.

Navigation elements, buttons, page content, metadata, and other interface text are displayed according to the active locale, ensuring a consistent structure and user experience across all language versions.

SEO Optimization

The following features were implemented to improve search engine indexing and link-sharing previews:

  • Page-specific titles and descriptions
  • Open Graph metadata
  • Canonical URLs
  • Sitemap
  • Robots configuration
  • Semantic HTML structure
  • Multilingual page references
  • Image alternative text
  • HTTP-to-HTTPS redirection

Deployment and Domain Configuration

The website is packaged and deployed using Docker on DigitalOcean, with Nginx serving as the reverse proxy.

Cloudflare handles DNS management, HTTPS, and traffic proxying. Redirects between the root domain, the www domain, HTTP, and HTTPS were also configured to ensure that users are always directed to the correct and secure version of the website.

Project Outcome

This project was developed around the client’s actual business requirements and covered the complete process of content organization, information architecture, design, development, deployment, and long-term maintenance planning.

Through reusable components, structured data, and a headless CMS, the website can continue to grow and receive content updates while maintaining a consistent visual style. The client can also manage article content independently, reducing the maintenance cost associated with developer-led code changes and redeployment.