The logo that closes the chain
After making the auth service product-aware and building the product catalog, the flow was technically correct. The right tenant sent the email. The right redirect landed the user in the right app.
But the email header was blank. The password setup page had no logo. The user was in the right place for the wrong reasons — they had to trust the URL, not the visual identity.
The gap between "technically correct" and "visually coherent" is where user trust lives.
The missing link
The catalog had the logo. The auth service had the product metadata. The notification service rendered the email. None of them were connected on the visual side.
The logo needed to travel the same path as the product code:
Two surfaces, same source. When the admin uploads the logo once, both surfaces pick it up — no additional wiring per surface.
What changed in the email
The email layout already had a logo slot. It was unused because the tenant config did not carry a logo URL. Once the product catalog started including logoUrl in the tenant reference, the notification service rendered it.
One constraint that matters in email HTML: the logo must degrade gracefully. Not every email client renders images. The alt attribute must say the actual product name, not "logo" or an empty string. If the image does not load, the user still reads the brand name.
What changed on the auth page
The action token already carried product metadata for the redirect. Adding logoUrl to that metadata meant the password setup page could render the correct logo without any additional API call.
The page reads the token, gets the logo, renders it above the form. The user sees a familiar mark before they type anything. That is the moment trust is either present or absent.
Why this was the last piece
The logo was not the first thing to fix. It was correct to fix it last.
Getting the routing right — which product, which tenant, which redirect — is structural. Getting the logo right is confirmation. Adding visual polish before the routing works creates a coherent-looking broken flow. Adding it after creates a coherent working one.
The order was: product context first, then routing, then visual identity. Each layer assumed the one below it was stable.
Part of my platform notes. Follow the blog or contact me.