A submitted upload looked completely lost. The form completed, no error appeared, but the content never surfaced where it was supposed to. The actual problem had nothing to do with the upload itself. A redirect inside the read route was intercepting the slug and sending the browser somewhere else entirely.
What the Symptom Looked Like
The upload went through. No failure state, no error message. But when anyone navigated to the expected news URL, they landed on a magazine edition instead. From the outside it looked like the content had disappeared. From the inside, the data was sitting in the database untouched.
That gap between "the write succeeded" and "the read fails silently" is where this class of bug hides. The submission layer and the display layer are separate, and a fault in the display layer can make a healthy submission look broken.
Where the Redirect Was Hiding
The project used a dynamic route component, something along the lines of news/[slug].vue. Inside that component there was a redirect branch. The branch was meant to handle a specific set of slugs that belonged to a magazine edition, routing them away from the news view and into the edition view.
The problem was that the slug pattern matched too broadly. When a new news item was submitted with a slug that happened to collide with the pattern the redirect was checking, the component caught it and sent the browser to the magazine edition. The news item existed. It just never got a chance to render.
This is easy to miss because the redirect is doing exactly what it was written to do. It is not broken in isolation. It is only broken in combination with the new slug.
How the Fix Was Structured
The recorded fix had two parts, and both were necessary.
- Remove the redirect branch from
news/[slug].vueand the other link paths that were participating in the same pattern. Without this step the content stays unreachable. - Repair the links in the news list and on the homepage so they point directly to the correct news URLs. If those links were relying on the redirect to resolve correctly, removing the redirect breaks them.
Doing only the first part leaves broken links. Doing only the second part leaves the redirect in place to swallow future slugs. The fix has to be end to end.
Why the Content Was Never Actually Lost
It is worth being explicit about this. No data loss occurred. The upload completed successfully and the content was queryable throughout. The routing layer was the only thing broken.
This matters because the instinct when content "vanishes" is to look at the write path: did the upload fail, did the database reject it, did a background job drop it. In this case all of that was fine. The fault was entirely in how the read route handled the slug after the fact.
Checking the read route first, before assuming write failure, would have shortened the debugging loop considerably.
The Guard Rails Worth Adding
Two patterns came out of this as suggested guard rails, not as measured outcomes.
Return after navigateTo. When a redirect is intentional, the component should return immediately after calling navigateTo. Without the return, the component continues executing after the redirect is triggered. That makes the redirect harder to reason about and can produce unexpected behaviour in edge cases.
Explicit link targets. Links in the news list and homepage should point to the exact path the content lives at, not to a path that relies on a redirect to resolve correctly. Redirect chains as a routing strategy accumulate technical debt quickly. Each link that depends on a redirect is a link that breaks silently if the redirect changes.
Neither of these is a dramatic architectural change. They are small habits that make the routing layer easier to read and easier to debug.
Keeping Slug Namespaces Distinct
The root cause here was a slug collision between two route types: news items and magazine editions. They shared enough of a pattern that the redirect branch could not tell them apart.
The cleaner long-term fix is to keep those namespaces distinct at the data level, not just the routing level. If magazine edition slugs and news slugs can never collide by construction, the redirect branch becomes unnecessary. You do not need routing logic to compensate for an ambiguity that should not exist in the first place.
This is related to a broader point about URL design. Every URL on the site should resolve unambiguously to one thing. If two content types can produce the same slug, you have a latent bug waiting for the right content to trigger it. See also the note on every URL on the apex host for how that principle applies to canonical routing more broadly.
Debugging Checklist for Missing Uploads
When submitted content does not appear where expected:
- Check the write path last. Confirm the submission completed without errors, then move on.
- Check the read route first. Open the dynamic route component for the content type and look for redirect branches.
- Test the slug directly. Navigate to the exact URL the content should live at and watch where the browser ends up.
- Check slug collisions. Look at whether the slug matches any pattern used by a different content type.
- Audit the links. After fixing the route, check every link in lists and on the homepage that points to that content type.
What I'd do differently
Start with the read route, not the write path. The instinct to check whether the upload failed is reasonable, but it costs time when the submission layer is healthy and the fault is in routing.
I would also add slug collision detection earlier in the content creation flow. If the system can warn at submission time that a slug matches a pattern reserved for a different content type, the problem never reaches production. That is a small validation rule with a disproportionate payoff.
And I would apply return after navigateTo consistently from the start, not as a retrofit. It is one of those conventions that is trivial to add when writing the code and annoying to track down when it is missing.




