In my last post, I showed how to canonicalize a domain in phoenix in that post I had a bug. I was properly redirecting users to the desired canonical domain, however I was using a 302 redirect instead of a 301, and a 301 should be use for canonicalization.
In Elixir's Phoenix framework, redirects default to responding with 302. This tells the browser the path was found but temporarily moved to a new location. The browser will respond redirecting the user, and for all intents are purposes from the user perspective a 301 and 302 are identical, however search engines and other web crawlers handle these kinds of redirects very differently. A 302 redirect tells search engines we may want to use this in the future, so don't forget to come back. They are catalogued and recorded as needing to be visted later in case the temporary redirect is removed and the original location has been restored. This is useful if we only want to move a page for a short period of time, or we want to change that redirects ending location in the future. This is the safest behavior from an SEO stand point since it won't cause a search engine to ignore any URL on your site, but what if we want to tell search engines that path will never again be used except to move the user to the new location, so please don't bother checking it again? We can do this using a 301 or "moved permanently" redirect.
In Phoenix we have to be explicit about what our status is going to be. So we use the put_status/2 function to add a status of :moved_permanently to the connection before we redirect. If no status is set then the redirect will respond with a 302.
conn |> put_status(:moved_permanently) |> redirect(to: some_path(conn, :some_action))
In the above example, you can use 301 instead of :moved_permanently, but I think using the atom version is much more readble.