Iron router and prerender 301 redirects

This is a post about my struggles with prerender redirects using iron router. I’m not sure if this problem is solvable, I may have to go back to the drawing board. Maybe someone here may have similar experiences.

So I have a thing in my app where if you type
(123456789 would be an id)
You’ll get redirected to a more descriptive URL

Even something like
Would also redirect to

There is one single canonical URL for each todo item, but potentially infinite redirects. For google I use a canonical URL meta tag, but that’s irrelevant to prerender.

So I’m trying to prerender this route. And using prerender best practices, I

  1. Turn off this redirect if the user-agent is prerender. (So the url stays
  2. I insert into the meta tags
    prerender-status-code -> 301
    prerender-header -> The canonical URL (Location:
  3. I set window.prerenderReady = true

So the expected behavior would be that prerender would only cache the canonical page, and redirect these other potentially infinite URL’s to that cached page when accessed by googlebot.

But that’s not happening.

(Sidenote: All the cases I’m about to go over happen before window.prerenderReady is set to true, I’ve determined that’s largely unimpactful).
First I tried setting the meta tags in the blaze template onRendered This didn’t seem to work.

Next I put them in the routers onBeforeAction. That also didn’t work.

Finally I put them in the routers waitOn, doing it immediately after the publication for todos return (Which is necessary to get the canonical URL). This also did not work.

What did end up working best was actually my first idea, which was using ostrio:iron-router-meta to set the router tags that way. When I did this, the expect behaviour that I want (Prerender sensing a 301 and delivering the redirected page) happens.

But ONLY when I spoof googlebot myself in chromes dev tools and visit my website.

Googlebot itself does not see a difference. It still makes requests that prerender doesn’t sense the 301 for and makes false dupe pages still when it asks for them, despite it being the same page I’ve tested myself when spoofing googlebot and successfully getting the 301 code in prerenders console and correct behavior that I want.

So I’m scratching my head, the only difference I’ve noticed with the meta functions from ostrio:iron-router-meta is that they run more then once. I suspect it’s because they’re reacting to publication data coming back from the server.

So you might think the problem is that they’re being filled with bad data because the mongodb collections aren’t initially available yet to make the canonical URL off of. Except I’m using fastrender which solves that problem and they seem to run correctly even the first time they’re called.

So I don’t know.

Another interesting note is that marking a page as “404” is trivial. I can do it on the onRendered callback even (Which is the final piece of code that runs before prerenderReady is set to true) and it works just fine for me OR the actual googlebot. I wonder if there’s just some oversight I’m missing.

Hi there! That seems weird. Usually the only problem we see people run into when doing a javascript redirect and trying to use the prerender-status-code meta tag is the fact that some setups clear out any old tags after the redirect happens, causing the prerender-status-code meta tag to disappear before we can look for it.

It doesn’t sound like that’s what is happening here though. Would you mind emailing us at We’d be happy to do some debugging with a prerender server and see what’s going on here.


I think I’ve figured this out.

In order to tell if the visiting agent is prerender I was going off their user agent listed here
However I noticed here
That they say that they may update the chrome version, which would change the user agent string (And the one listed is really out of date, the current chrome version is 80. So It’s likely they have updated since then.)

So I’m going to do a much less strict check on the user agent string, and I’m betting this will probably work. :wink: