FullstackPhoenix

Branded 404 and 500 Error Pages for Phoenix

phoenixerror-pagesliveviewsaas

A customer shares a link to one of your case studies on LinkedIn, then the marketing team renames the slug a week later. Anyone clicking the old link hits the Phoenix default "Not Found" plain-text page — no logo, no nav, no way back into the product. That is the exact moment your branding evaporates and a warm referral cools off.

This feature replaces the default Phoenix error responses with real templates that look like the rest of your application. You stop apologising for the framework on your worst pages, and your LiveViews get a clean way to raise "not found" without an Ecto.NoResultsError stack trace bubbling into production.

Keep the brand intact when something goes wrong

A 404 is often the first impression of your domain that a non-customer ever sees. Making it look like your app — logo, typography, "back to home" link — is a small change with an outsized effect on perceived quality. The 500 page matters even more, because that is the page someone sees while they are already frustrated.

What This Feature Adds

  • lib/my_app_web/controllers/error_html/404.html.heex and 500.html.heex templates rendered in your app's style
  • A replace on lib/my_app_web/controllers/error_html.ex that uncomments embed_templates "error_html/*" so the templates are actually picked up
  • A MyAppWeb.Fallback exception module that LiveViews can raise to return a 404 cleanly
  • An update to the generated error tests so they match against the new templates with a regex instead of an exact string

How It Fits Into Your Phoenix Application

Phoenix already wires ErrorHTML into its endpoint. This feature flips one line in that module and drops two templates next to it. The Fallback module lets a LiveView signal "this resource does not exist" without leaking the underlying Ecto.NoResultsError:

defmodule MyAppWeb.PostLive.Show do
use MyAppWeb, :live_view
def mount(%{"id" => id}, _session, socket) do
case Posts.get_post(id) do
nil -> raise MyAppWeb.Fallback
post -> {:ok, assign(socket, :post, post)}
end
end
end

The 404 template uses gettext/1 so the copy can be translated alongside the rest of the app.

Installation Notes

There are no required dependencies and nothing to add to config.exs. Two things worth knowing before you ship:

  • In dev, Phoenix shows the debugger by default. To preview the real 404 / 500 pages locally, temporarily set debug_errors: false in config/dev.exs.
  • Customise the markup in 404.html.heex and 500.html.heex to match your brand — fonts, illustrations, support email. The defaults are a starting point, not a finished design.

Build This With Live SaaS Kit

Install saas_kit, set your boilerplate token, and run mix saaskit.feature.install 404_page to get branded error pages with a sensible LiveView fallback in one step.