How I Built and Deployed This Site in a Weekend (With Full SEO and No Backend)

April 19, 2025

Author: Michael Goodwin

Cover image for How I Built and Deployed This Site in a Weekend (With Full SEO and No Backend)

When you visit undercroftlabs.com, you'll find a site I built over a single weekend. It's fast, secure, SEO-optimized, and completely static. There’s no backend, no CMS, no database.

Rather than relying on heavyweight frameworks or external services, I chose a lean stack: Next.js, Markdown, Tailwind, and TypeScript.

Here's a breakdown of how it works.

The Stack

  • Framework (Next.js 15): featuring the modern App Router architecture, organized in the app/ directory for intuitive routing and improved performance.

  • Styling (Tailwind CSS): provides utility-first styling, enhanced with DaisyUI for polished, pre-built components that speed up development.

  • Content Management (Markdown + MDX): integration through @mdx-js/loader and next-mdx-remote, allowing for rich content creation with React components.

  • Infrastructure: Hosted on DigitalOcean App Platform, with static exports (next export) served through their global CDN for optimal performance.

The result? A lightweight architecture with no runtime servers, databases, or CMS. It easily delivers pure static HTML, JS, and CSS.

Project Structure

The site leverages Next.js's App Router, managing all routing within the app/ directory. Pages use generateMetadata to define their metadata, while blog posts are statically generated from the /content/ folder.

Pages

  • Homepage (app/page.tsx): The main landing page that introduces visitors to the site and showcases key features.

  • Blog Index (app/blog/page.tsx): A directory of all blog posts, organized chronologically with previews and metadata.

  • Blog Posts (app/blog/posts/[slug]/page.tsx): Individual article pages that are dynamically generated at build time from Markdown content.

  • Libraries (app/libraries/page.tsx): A showcase of open-source tools and projects, complete with documentation and usage examples.

  • Static Pages (app/site/*): Essential pages including legal documentation (Terms, Privacy) and company information (About).

Content

All blog content is stored in flat Markdown/MDX files within content/blog/posts/. Each file contains frontmatter with metadata like title, description, author, and publish date. I parse these using gray-matter. Here's what a post looks like:

---
title: "How I Built and Deployed This Site in a Weekend"
description: "A behind-the-scenes look at Undercroft Labs."
author: "Michael Goodwin"
published: "2025-04-19"
slug: "undercroft-site-architecture"
---

The rest of the content goes here...

There's no CMS, login, or WYSIWYG editor. I simply write and push.

SEO Optimization

Each page is optimized with structured metadata to improve search engine visibility and social sharing. The metadata includes essential elements like titles, descriptions, and canonical URLs, along with specific structured data to help search engines better understand the content. This includes:

  • Dynamic Metadata Generation: Each page uses Next.js's generateMetadata() function to dynamically create custom metadata, ensuring accurate and targeted SEO information for every route.

  • Social Media Integration: Comprehensive Open Graph and Twitter card tags are implemented to optimize content sharing across social platforms, with rich previews and descriptions.

  • Structured Data: Custom <ArticleJsonLd /> component adds JSON-LD markup to blog posts, helping search engines better understand and display content in search results.

  • Search Engine Essentials: Static robots.txt and sitemap.xml files are included to guide search engine crawlers and ensure proper indexing of all site content.

  • Legal Page Optimization: Dedicated JSON-LD schemas for legal pages (Privacy, Cookies, Terms) improve their discoverability and provide clear context to search engines.

Why Static?

  • Speed: Static sites excel in performance since there are no database queries or server-side processing. Every page is pre-rendered, allowing for near-instant load times.

  • Security: With no server-side runtime environment or database, the attack surface is minimized. There's virtually nothing to hack or exploit since it's just static files being served.

  • Simplicity: The entire codebase is version-controlled and easy to maintain. No need to manage separate systems, the content and code live together in one place.

  • Scalability: Static files can be distributed across global CDN networks effortlessly. There's no complex infrastructure to manage, and the site can handle massive traffic spikes without breaking a sweat.

All of content is exported to the /out directory and pre-rendered during the build process. I can test it locally by running npx serve ./out. I don't need a runtime or extra tooling. It just loads.

Hosting & Deployment

The final site is deployed using DigitalOcean App Platform. It happens through these easy steps:

  • Git Push: I simply push the changes to the main branch to trigger the deployment process.

  • Automated Build: DigitalOcean App Platform automatically runs the build process using 'npm run build' to generate static files.

  • CDN Distribution: The generated static files in the /out directory are automatically distributed across DigitalOcean's global Content Delivery Network.

  • Zero-Config Deploy: The entire process requires no manual configuration and delivers blazing-fast performance with minimal overhead.

Final Thoughts

This setup provides everything needed for a fast, SEO-friendly site that I control completely.

If you don't need all of that extra tooling and just want to get your content in front of your audience, then don't waste time with it.

Questions? Ideas? Feel free to explore the libraries page to see what else I'm working on.