A static portfolio can be simple to read and still have routing behavior worth testing.
My portfolio stores articles as HTML files, but I share extensionless addresses. That creates a small contract between the file on disk, the hosting configuration, and the link a reader bookmarks. I want those parts to agree before I call a publication complete.
This is the practical routing companion to my article about keeping a portfolio in static HTML. Here, I am concentrating on the checks behind a single published address.
Start with two requests, not one screenshot
For my recent architecture article, these addresses have different jobs:
-
/why-i-keep-portfolio-static-html-frank-smith-iiiis the public destination. -
/why-i-keep-portfolio-static-html-frank-smith-iii.htmlis the file-shaped address that should send a visitor to that destination.
Opening the clean URL and seeing the correct heading tests only one path. Someone arriving through an older link may take the second path. A screenshot of the first page does not tell me what happens to that visitor.
I write the expected behavior down before changing a rule: the clean address should return the article, while the file-shaped address should redirect to it. That gives me something specific to verify after deployment.
Separate serving a file from moving the browser
These are the two corresponding rules in my Netlify configuration:
[[redirects]]
from = "/why-i-keep-portfolio-static-html-frank-smith-iii"
to = "/why-i-keep-portfolio-static-html-frank-smith-iii.html"
status = 200
[[redirects]]
from = "/why-i-keep-portfolio-static-html-frank-smith-iii.html"
to = "/why-i-keep-portfolio-static-html-frank-smith-iii"
status = 301
force = true
They are not interchangeable. In Netlify, the 200 rule is a rewrite: it serves the target while keeping the requested address. The 301 rule redirects the visitor. Netlify explains rewrites here.
The force setting matters in this example because the HTML file exists. Netlify normally lets an existing file take precedence over a matching unforced redirect. Its redirect options documentation describes that behavior.
I would not copy this pair into an unrelated site's configuration without checking the other rules. The useful lesson is to identify which request should serve content and which should move to another address.
Inspect the response before following it
I use a header request to inspect each entry point:
curl -I https://franksmithlll.com/why-i-keep-portfolio-static-html-frank-smith-iii.html
curl -I https://franksmithlll.com/why-i-keep-portfolio-static-html-frank-smith-iii
In Windows PowerShell, I use curl.exe explicitly.
On September 16, 2026, the file-shaped address returned 301 with a Location header pointing to the clean path. The clean address returned 200 and Content-Type: text/html; charset=UTF-8. Those are observations from this deployment, not promises about every future deployment.
I deliberately inspect the initial redirect before using an option that follows it. Otherwise, a successful final response can hide an unexpected intermediate destination. I then open the public page to check its actual content; headers alone cannot prove that the correct article was served.
Keep the document's address consistent
Routing is only one part of my check. In the deployed HTML, I review the canonical URL, article URL in structured data, and links from the Blog index. In the sitemap, I look for the same clean destination.
A canonical tag is not a replacement for testing a redirect. Likewise, finding a URL in a sitemap does not establish that the server returns the intended document. I treat each as a separate assertion that needs to match the public page.
I also check the article's image and internal links. A correct address with missing content is still an incomplete result.
Treat a host migration as a behavior migration
My source files are straightforward to move, but netlify.toml is not a universal server configuration. A different host would need equivalent routing behavior in its own format.
My migration checklist therefore includes old entry points, final destinations, response headers, and the rendered article. I would compare those outputs rather than assume that copying the HTML preserved the whole site.
The portfolio repository itself is private. The deployed pages are public, and my GitHub profile links the project source that is publicly available.
For me, the value of a small static site is that I can name and inspect these responsibilities. The check is not simply "does the page open?" It is "does each supported address lead to the document I intended?"
I am Frank Smith III, a full-stack developer and Field Operations Specialist in Bergen County, New Jersey. More project notes are on my portfolio blog.
Top comments (0)