How to redirect from non-www to www with Traefik
Tags: traefik, architecture, tooling, devops
Published: 2021-09-24 14:52:36

---
title: How to redirect from non-www to www with Traefik
published: true
date: 2021-09-02 23:15:00 UTC
tags: traefik, architecture, tooling, devops
canonical_url: https://www.benjaminrancourt.ca/how-to-redirect-from-non-www-to-www-with-traefik
cover_image: https://www.benjaminrancourt.ca/images/pexels-jens-johnsson-66100.jpg
---
I recently switched the hosting provider of my personal blog from [Netlify](https://www.netlify.com/) to my custom stack ([Docker](https://www.docker.com/), [Portainer](https://www.portainer.io/) and [Traefik](https://doc.traefik.io/traefik/)) and I quickly noticed that I had forgotten something in my migration: the redirection from [benjaminrancourt.ca](https://benjaminrancourt.ca/) to [www.benjaminrancourt.ca](https://www.benjaminrancourt.ca/)... 😟

Even though my website contains [canonical link elements](https://en.wikipedia.org/wiki/Canonical_link_element) and the same website was served for both domains, it bothered me that I lost this little feature... So naturally, I started searching on the internet for how to implement this redirection with Traefik. 😇

Unfortunately, although the Traefik community has asked similar questions several times in the past ([5425](https://community.traefik.io/t/redirect-www-to-non-www-not-working-in-v2/5425), [6458](https://community.traefik.io/t/ridirect-www-to-apex-domain/6458), [6813](https://community.traefik.io/t/http-to-https-redirection-difference-in-using-cli-vs-middelwares/6813), [8409](https://community.traefik.io/t/global-redirect-from-non-www-to-www-with-traefik-v2/8409), [7428](https://community.traefik.io/t/v2-2-8-global-redirect-www-to-non-www-with-http-to-https/7428), [8976](https://community.traefik.io/t/v2-3-5-www-to-non-www-redirect/8976) and [10711](https://community.traefik.io/t/v2-4-8-www-to-non-www-redirect/10711)), none of the suggested solutions worked for my environment... 😢

Most of them define a new middleware with `labels`, but I was looking for a more global solution that I could apply only to some sites. I considered that it was not very efficient to create a new middleware to resolve the redirect for every website that needs it... 🤔

In particular, the solutions were not all the same, but they were similar to each other:

```yaml
  - "traefik.http.middlewares.wwwtohttps.redirectregex.regex=^https?://(?:www\\.)?(.+)"
  - "traefik.http.middlewares.wwwtohttps.redirectregex.replacement=https://$${1}"
  - "traefik.http.middlewares.wwwtohttps.redirectregex.permanent=true"

```

Some of them escape the period twice (`\\.`), while others escape it only one (`\.`) and others don't escape it (`.`)... There were also two variations for the double dollar sign (`$${1}` and `${1}`)... Which one is correct? A little bit confusing, right? 😵

So I started trying out several combinations and after breaking my live website a couple of times, I finally got it to work! Below is the solution that works for me with Traefik v2.5.1. 🎉

## **Solution**

As I said above, I define the middlewares only once, in the [dynamic configuration file](https://doc.traefik.io/traefik/getting-started/configuration-overview/):

```yaml
# Traefik dynamic configuration file
# See https://doc.traefik.io/traefik/getting-started/configuration-overview/#the-dynamic-configuration

http:
  middlewares:
    # Redirect non-www URLs to their www equivalent
    # Use with traefik.http.routers.myRouter.middlewares: "redirect-non-www-to-www@file"
    redirect-non-www-to-www:
      # Redirect a request from an url to another with regex matching and replacement
      redirectregex:
        # Apply a permanent redirection (HTTP 301)
        permanent: true
        # The regular expression to match and capture elements from the request URL
        regex: "^https?://(?:www\\.)?(.+)"
        # How to modify the URL to have the new target URL
        replacement: "https://www.${1}"

    # Redirect www URLs to their non-www equivalent
    # Use with traefik.http.routers.myRouter.middlewares: "redirect-www-to-non-www@file"
    redirect-www-to-non-www:
      # Redirect a request from an url to another with regex matching and replacement
      redirectregex:
        # Apply a permanent redirection (HTTP 301)
        permanent: true
        # The regular expression to match and capture elements from the request URL
        regex: "^https?://www\\.(.+)"
        # How to modify the URL to have the new target URL
        replacement: "https://${1}"

```

You might have already noticed how to use them in my comments, but it only takes to add a new label to your `docker-compose.yml` file:

```yaml
  traefik.http.routers.myRouter.middlewares: "redirect-non-www-to-www@file"

```

And if your router already has a middleware, just add the middleware you want by separating them with a comma (`,`) like `another-middleware,redirect-non-www-to-www@file`.

So that's it, you can now redirect your websites to www or non-www. 🤗