· Chris Hammond
Last Updated

Using Netlify and Astro to handle 20+ years of blog urls

How I handled URLs after migrating to Astro

How I handled URLs after migrating to Astro

Because I’ve had my blog up and running in some form for 20+ years now, I have thousands of blog posts, which means thousands of URLs as well. Over the years I have run the blog on DotText, CommunityServer and DotNetNuke, and as of earlier this month, Astro.

This has caused me to have URL sprawl that is hard to fathom, even just when the site ran on DotNetNuke the URLs changed probably 4 or 5 times as I upgraded to use new features in both the DNN Platform, various friendly URL providers, and even upgrades to Engage Publish, the blogging engine that I maintained a fork of for DNN.

In DNN, it wasn’t too difficult to setup redirects and have the URLs properly “generated” as the format and structure of the URLs changed, mainly because I was maintaining the C# code for EngagePublish, but how do you do something similar with a statically generated site built on AstroJS?

To handle URLs for ChrisHammond.com I found that running the website on Netlify gave me the flexibility of using a _redirects file. A Redirects file on Netlify allows you to populate a simple text file to provide URL redirection with proper HTTP status codes, so you can provide the OLD url and the NEW url, and Netlify will handle the redirect for you. This allows you to not actually need to go through every blog post and change the links to the new URLs.

The _redirects file with Netlify

To use a _redirects file with Netlify, put a file called “_redirects” in the /public/ folder in the root of your Astro project.

Here are some examples of the URLs I setup in my _redirects file.

In some cases, I previously had a DNN page, for example /cars/Corvette, that would show a list of blog posts with the Corvette tag. Now using Astro I just want to redirect to the /tag/Corvette url and let astro build out that list.

# OLD_URL NEW_URL STATUS_CODE  
/Cars/Corvette/ /tag/corvette 301  
/cars/corvette /tag/corvette 301  

That will redirect those calls to the Astro page for that tag

Now getting into specific blog posts, I initially converted all the Engage Publish articles (blog entries) to a CSV file that I then used to create .MD files for each post, I may cover some of that detail in the future, but as we’re talking about URLs in this blog post, let’s cover how I handled some of those redirects.

I created a powershell script that ultimately created the OLD URL along with a NEW URL for each of the MD files. Using this information I was able to create a list of URLs to put into the redirects file. Here’s an example of a blog post, on Engage Publish the URL was /blog/itemid/1664/2008-website-statistics, and for Astro the new url for the post is /2009/2008-website-statistics, where 2009 is the year it was published, followed by the title of the blog post. But, older versions of DNN/EnagePublish used .ASPX extensions, so I also wanted to account for any remaining links to the blog with the .aspx extension, so ultimately in my redirects file I have two entries.

# OLD_URL NEW_URL STATUS_CODE  
/blog/itemid/1664/2008-website-statistics /2009/2008-website-statistics 301  
/blog/itemid/1664/2008-website-statistics.aspx /2009/2008-website-statistics 301  

If I wanted to account for case sensitivity I might have additional entries for different variations

# OLD_URL NEW_URL STATUS_CODE
/Blog/ItemId/1664/2008-Website-Statistics /2009/2008-website-statistics 301 

My redirects file is currently over 3 thousand lines, which Netlify will use to generate the proper redirect handling for most of my URLs.

Netlify.toml

In addition to the blog URLs though, I wanted to configure proper handling for TAGS and PAGING that occurred on the site using DNN/EngagePublish. I couldn’t get the redirects file to do that without just enumerating over every tag and potential paging combination, which probably would have added another couple of thousand lines. I was able to solve this another way, using a netlify.toml file in the root of my project. Inside of that toml file I added 3 redirect rules, one for the paging, and one for the tags (2 for case sensitivity for tags).

[[redirects]]  
  from = "/home/catpageid/*"
  to = "/blog/:splat"
  status = 301
[[redirects]]
  from = "/tags"
  to = "/tag/:id"
  query = { tags = ":id" }
  status = 301
[[redirects]]
  from = "/Tags"
  to = "/tag/:id"
  query = { tags = ":id" }
  status = 301

One thing to keep in mind, these redirects won’t work in your locally running instance of Astro, unless you get the Netlify CLI running locally, which is super useful for testing to ensure your redirects at working properly. I have Astro running on a Ubuntu based Linux VM, so installing Netlify and running locally is pretty easy with the following commands.

npm install -g netlify-cli
netlify --version
cd /path/to/your/project
netlify dev

Here are some final _redirects entries that I used to handle some additional page and other redirects I wanted to manage. You might notice that some of these redirects actually go to external URLs, you can do that in the _redirects file as well!

/blogs/archive/* /blog 301
/philanthropy /tag/philanthropy 301
/philanthropy.aspx /tag/philanthropy 301
/Philanthropy /tag/philanthropy 301
/events/ https://rainbowmarks.com/events 301
/tag/events https://rainbowmarks.com/events 301
/photos.aspx https://rainbowmarks.com/ 301
/tags /blog 301
/contact.aspx /contact 301
/blog/itemid/* /blog 301
/Blog/itemid/* /blog 301
/DesktopModules/EngagePublish/printerfriendly.aspx / 301
/DesktopModules/EngagePublish/printerfriendly.aspx* / 301
/login / 301
/login* / 301

Understanding Redirect Order in Netlify: netlify.toml vs _redirects

When setting up redirects in Netlify, you might wonder: Does netlify.toml get loaded before _redirects? The short answer is yesnetlify.toml takes precedence over _redirects.

Order of Precedence

  1. netlify.toml – This is the primary configuration file for Netlify. Redirects defined here take precedence over _redirects.
  2. _redirects – If a redirect is not found in netlify.toml, Netlify will then check _redirects.

Behavior

  • If both files have conflicting redirects, the rule in netlify.toml wins.
  • If netlify.toml does not define a certain redirect, Netlify will check _redirects.
  • _redirects is processed after netlify.toml, meaning any undefined rules in netlify.toml may still be picked up from _redirects.

Example: Conflict Between Files

netlify.toml

[[redirects]]
  from = "/old-page"
  to = "/new-page"
  status = 301

_redirects

/old-page /another-new-page 301

➡️ In this case, /old-page will redirect to /new-page because netlify.toml takes priority.

Best Practices

  • If you have complex or structured redirects, use netlify.toml.
  • If you prefer a simpler format, use _redirects, but note that it won’t override rules in netlify.toml.
  • If you use both, ensure there are no conflicting rules to avoid confusion.

By understanding how Netlify processes these files, you can configure your redirects effectively and avoid unexpected behavior. 🚀

Back to Blog

Related Posts

View All Posts »