Trouble with Permalink redirects due to fragment after "#" not being sent to server

EDIT: changed topic title to fit what I discovered to be the problem, thanks to the answers below

I’m getting a weird behaviour with permalinks on my migration work.

My problem is not the one about internal links not redirecting. I am just trying this by pasting URLs into my browser’s address bar.

These are the two redirects I mean to happen in my tests:

that’s a post redirect, should redirect to the second post like this:

that’s a topic redirect, should go to:

I know my normalizations are working fine. My regexp is


And I check them in the rails console:

irb(main):069:0> Permalink.normalize_url('')
=> "normalized.17978.16249"

irb(main):068:0> Permalink.normalize_url('')
=> "normalized.17978."

That is what I intended. I have this in my Permalinks table:


And this is what it looks like from the database:


But when I put this into the browser URL

it gets redirected to

Instead of what it should be

So I see the first post, it doesn’t scroll to the second one as it should.

Why is that #16249 hash getting added back, if my normalization removed it?

Another way to expose this incongruence (although a bit artificially) is to try the following redirects from the browser’s address bar:
correctly redirects to:

correctly redirects to

So why doesn’t it work when going through the normal process?

Permalinks only works for incoming links, it’s right there in the description.

You will need to correct internal links.

1 Like

I mentioned in the beginning of my post that this is not the case, I am not clicking on links in my own forums.

But maybe I am not understanding what is meant here by “internal links”, can you explain better? If I paste a URL in the browser’s address bar, how is that an internal link?

The URL fragment identifier (the # and anything after) is never sent to the server by the browser - you can’t use that as a part of a redirect.


Now that you say that, it makes sense… but is quite depressing.

I guess that completely rules out proper post-level redirects from my old forums, since they use # for that :sob:

Is this a common limitation people have faced in migrations? This is Kunena software, I guess it’s pretty common, and I bet others also use hashes to link to posts…

I’ve been going over this in my head. It’s such an annoying limitation. I guess the basic mistake was made long ago, by the Kunena forums designers, in using just fragments to mark post-links… sigh.

I see 3 approaches that could Discourse could use to work-around this (I’m going clearly into wishful thinking territory here, enjoy the ride)

  1. Javascript kicks in when the page loads, recognizes there’s a hash fragment in the URI, and uses it to call the server and re-redirect to the proper place. Works, but you get a double-redirect, and the user sees the page reloading.

  2. Discourse could add (server-side) an id tag with the old imported post_id to each post’s HTML. This way the browser would transfer the old hash id, and use it in the redirected page, scrolling to the bottom. Main caveat: Discourse’s fancy scrolling, where posts are only loaded when you scroll to them, makes this scheme insufficient.

  3. A mix of the above: Discourse builds (server-side) a table of correspondence between old import post_ids and new post_numbers, and sends it to the client when the page loads. Javascript on the client recognizes that there’s a hash in the URI, translates that hash using the table and uses it’s own scrolling functions to go down to the correct post.

This would be laborious to implement, and have a performance penalty. It would allow the perfect migrations to occur, though…

These are not complete solutions because redirects still won’t work unless the user is already in Discourse. External links are much less likely to arrive that way.

My current approach for the internal/external redirects is this:

My old site is at, the new one at

When the migrated server goes live, we do a Gateway redirect from the old to the new.

I leave my internal links unchanged, starting with When somebody clicks them, that’s external for all practical purposes. But then our Gateway redirect happens, and it comes back into Discourse, and the permalinks should kick in normally.

Right? I haven’t tried this out yet… I guess this would be impossible if we wanted to use the same domain name and folder, but we don’t.

What you need to do is use permalink redirects.

I often create permalinks like /oldpost/POST_ID and then write a permalink redirect to rewrite /forum./category/someslug#1234 to use those links.

1 Like

By “permalink redirect” do you mean the site setting permalink normalizations?

1 Like

Oops! Yes. Sorry. It was late for my brain.

1 Like

Ok :slight_smile:

But I am using Permalink normalizations (see my first post). Only the hash part doesn’t get sent to the server (ever) so unless there’s some client-side Javascript thing doing its magic, there is no way a forum that uses only hashes for post-level links is ever going to be properly migrated (in terms of redirections) to Discourse (or to any other software).

Sorry. I didn’t read that carefully enough. I thought that I’d used stuff after the hash before, but I guess that’s wrong. I remember a recent case where those hash post ids were there but I guess they client wanted only topic level redirects. I think that for 301s ending up at the right topic is likely good enough,

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.