Web Development

GitHub Pages: 3 Hacks for Clean Subdirectory URLs 2025

Tired of ugly .html URLs on your GitHub Pages site? Learn 3 simple to advanced hacks for 2025 to get clean, professional subdirectory URLs. Boost your SEO and UX today!

A

Alex Carter

A front-end developer and tech writer passionate about clean code and simpler workflows.

7 min read10 views

Let’s be honest. You’ve just built a beautiful, fast, and free website using GitHub Pages. You’re proud of your work, you’ve pushed your final commits, and you’re ready to share it with the world. You send the link to a friend: your-username.github.io/about.html. They click it, and that ugly .html extension just hangs there at the end of the URL, mocking your otherwise pristine creation.

We’ve all been there. In a world of clean, semantic web design, file extensions in URLs feel like a relic from a bygone era. They’re not just an aesthetic annoyance; they make URLs harder to remember, less professional to share, and can even have minor impacts on SEO. Fortunately, reclaiming your URL sanity on GitHub Pages is easier than you think. You don’t need to switch hosting providers or pull your hair out with complex server configurations.

This post is your definitive guide for 2025. We’ll walk through three distinct hacks—from dead-simple to powerfully automated—to achieve those clean, beautiful subdirectory URLs (like /about/) on your GitHub Pages site. Let’s dive in and clean things up.

Why Clean URLs Matter (A Quick Refresher)

Before we get into the “how,” let’s quickly touch on the “why.” Why bother with this at all?

  • User Experience (UX): Clean URLs are easier for humans to read, type, and remember. /services/consulting/ is far more intuitive than /services_consulting_page.html.
  • SEO Benefits: While not a massive ranking factor, search engines prefer well-structured, keyword-rich URLs. A clean structure helps search engine crawlers understand your site's hierarchy.
  • Future-Proofing: What if you switch from a static HTML site to a WordPress site or another CMS? A URL like /about/ can be maintained. A URL like /about.html reveals your underlying technology and can be harder to migrate without redirects.
  • Professionalism: It’s a small detail, but it signals quality and attention to detail.

Hack 1: The Classic "index.html" Folder Method

This is the original, most straightforward, and universally compatible method. It relies on a fundamental behavior of virtually all web servers: when you request a directory, the server automatically looks for and serves a default file, which is almost always index.html.

How it Works

Instead of having a file named about.html in your root directory, you create a folder named about. Inside that folder, you place your HTML file and rename it to index.html. That’s it! When a user visits your-site.com/about/, the server sees the /about/ directory and serves the index.html file within it.

Step-by-Step Guide

Let's say your project structure looks like this:

your-repo/
├── index.html
├── about.html
└── contact.html

To get clean URLs, you would change it to this:

your-repo/
├── index.html
├── about/
│   └── index.html
└── contact/
    └── index.html

Now, the following URLs will work perfectly:

Advertisement
  • your-username.github.io/ will serve the root index.html.
  • your-username.github.io/about/ will serve about/index.html.
  • your-username.github.io/contact/ will serve contact/index.html.

Pros & Cons

  • Pros: Foolproof, requires no configuration, works with any static site (plain HTML, or any generator), and is easy to understand.
  • Cons: It’s a manual process. For a site with many pages, creating folders and renaming files can become tedious. It can also make your local project directory feel a bit more cluttered.

Did you know that GitHub Pages has a secret weapon? By default, it runs your site through Jekyll, a powerful static site generator. Even if you don't think you're using Jekyll, if you have a bunch of Markdown or HTML files, GitHub is using Jekyll behind the scenes. We can leverage this to automate our clean URL creation.

Jekyll is controlled by a configuration file in your root directory called _config.yml. By adding a single line to this file, you can tell Jekyll how to structure your URLs (which it calls “permalinks”).

  1. Create the Config File: If you don’t already have one, create a file named _config.yml in the root of your repository.
  2. Add the Permalink Setting: Open the file and add the following line:
    permalink: pretty
  3. Commit and Push: Save the file, commit it, and push it to your GitHub repository.

That's it! Jekyll will now automatically take a file like about.md or about.html and build it as /about/index.html behind the scenes. You don't have to change your file structure at all. Your project directory stays clean and flat, while your live site has beautiful, clean URLs.

You can also get more advanced. For example, if you organize posts in subdirectories, you could use permalink: /:categories/:title/ to include categories in the URL.

  • Pros: Fully automated, “set it and forget it,” keeps your source directory clean, and offers powerful customization options.
  • Cons: This method requires you to use Jekyll's build process. If you're using a different static site generator (like Hugo or Eleventy) or want to disable Jekyll, this won't work.

Hack 3: The Modern Workflow with GitHub Actions

What if you're using a modern JavaScript-based SSG like Next.js, Eleventy, or Astro? Or maybe you just have a build step you need to run. In these cases, you often disable the default Jekyll build. This brings back the ugly .html problem. The solution? A custom build and deployment process using GitHub Actions.

How It Works

GitHub Actions allows you to define a custom CI/CD (Continuous Integration/Continuous Deployment) pipeline. We can create a workflow that does the following every time we push to our main branch:

  1. Builds our static site (e.g., runs npm run build).
  2. Takes the output (usually in a dist or build folder).
  3. Renames the files to create the clean directory structure from Hack #1 automatically.
  4. Deploys the final, modified files to GitHub Pages.

Step-by-Step Guide

  1. Disable Jekyll: Create an empty file named .nojekyll in the root of your repository. This tells GitHub Pages not to run Jekyll and to just serve the files as-is.
  2. Create a Workflow File: Create a directory path .github/workflows/ in your repository. Inside, create a new file, e.g., deploy.yml.
  3. Define the Workflow: Paste the following configuration into deploy.yml. This example assumes your build command is npm run build and the output is in a /build directory.
    name: Build and Deploy to GitHub Pages
    
    on:
      push:
        branches: [ "main" ] # Or your default branch
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
        permissions:
          contents: read
          pages: write
          id-token: write
        steps:
          - name: Checkout repository
            uses: actions/checkout@v4
    
          - name: Setup Node.js
            uses: actions/setup-node@v4
            with:
              node-version: '20'
    
          - name: Install dependencies
            run: npm install
    
          - name: Build static site
            run: npm run build # Your build command
    
          - name: Rename HTML files for clean URLs
            run: |
              find build -type f -name "*.html" | while read file; do
                if [[ "$file" != *"index.html"* && "$file" != *"404.html"* ]]; then
                  mkdir -p "${file%.html}"
                  mv "$file" "${file%.html}/index.html"
                fi
              done
    
          - name: Upload artifact
            uses: actions/upload-pages-artifact@v3
            with:
              path: ./build # Your build output directory
    
          - name: Deploy to GitHub Pages
            id: deployment
            uses: actions/deploy-pages@v4
  4. Configure Pages Settings: In your repository settings under "Pages," set the "Build and deployment" source to "GitHub Actions."

Now, every push to `main` will trigger this action, building your site and automatically restructuring the files before deploying. You get full automation with any tool you want.

Pros & Cons

  • Pros: The most flexible and powerful method. Works with any static site generator or build process. Fully automates the entire workflow.
  • Cons: The most complex to set up. Requires a basic understanding of YAML and CI/CD concepts. Can feel like overkill for a very simple site.

Comparison: Which Hack Is Right for You?

Still not sure which path to take? This table breaks it down for you.

Feature Hack 1: Folder Method Hack 2: Jekyll Permalinks Hack 3: GitHub Actions
Ease of Setup Very Easy Easy Moderate
Automation None (Manual) Fully Automatic Fully Automatic
Flexibility High (Works with anything) Low (Jekyll only) Very High (Works with anything)
Best For... Simple HTML sites, beginners Blogs, Jekyll-based sites Modern SSGs, complex projects

Conclusion: Clean URLs Are Within Reach

There you have it—three battle-tested methods to banish .html from your GitHub Pages URLs forever. No matter your technical comfort level or project complexity, a solution exists for you.

  • For the beginner or a simple project, the manual folder method is a quick and effective fix.
  • For the blogger or Jekyll enthusiast, enabling pretty permalinks is a no-brainer.
  • For the modern developer using the latest tools, mastering GitHub Actions provides ultimate power and flexibility.

Clean URLs are a small but significant detail that elevates your project from a simple repository page to a professional-looking website. So go ahead, pick the hack that fits your workflow, push your changes, and enjoy the satisfaction of a clean, polished URL. Happy coding!

Tags

You May Also Like