If you’ve moved from other forum software to Discourse using one of our import scripts, then you probably want all your hard-earned Google search results to continue pointing to the same content. Discourse has a built-in way to handle this for you as an alternative to writing nginx rules, using the permalinks lookup table.

The permalinks table allows you to set two things: a url to match, and what that url should show. There are a few options for defining where the url should redirect to. Set one of these:

topic_id: to show a topic

post_id: to show a specific post within a topic

category_id: to show a category

external_url: to redirect to a url that may not belong to your Discourse instance

For example, if your original forum’s topic urls looked like http://example.com/discussion/12345, and the url for that topic after the import is http://example.com/t/we-moved/987, then you can setup the mapping like this:

Discourse will then perform a redirect with http response status code 301 (permanently moved) to the correct url for topic id 345. The 301 should cause search engines to update their records and start using the new urls.

If you want some urls to redirect away from Discourse, you can do so by setting external_url:

The challenge will be how to add that rule to nginx from the application.

Adding an nginx rule has always been an option, but it should be added through your docker config, not from the application. The method described here is an alternative to writing nginx rules, but definitely not the only way to do it.

downey
as @neil pointed only none existing links that will result in a 404 will invoke a permalink lookup.
which is much better then checking on each requests.

My suggestion is targeting a simple common migration, where all old links can be identified immediately.
before going via the default path. Based on a single match rule and rewrite to permalinkController. which will allow it to skip any overhead that occur on the default path.

This option though if not supported from the application level (modifiing nginx rules from application space). will require an advance user intervention (editing docker builder config).
But will still need the implementation of a “permalinkController” and route on the application level.

It looks like if you have any routes defined in a plugin, the permalinks check will trigger when you access that route. I guess the plugin routes are only evaluated after all routes for the main app have been tried. This is turning out to be quite annoying as I’m using a lot of new routes in my ChattyMaps plugin

This is what I’ve ended up adding in my plugin as I know I won’t be using permalinks (and I’m the only one using my plugin

PermalinkConstraint.class_eval do
def matches?(request)
return false
end
end

Will be interested in knowing if there are any problems / disadvantages to doing this.

Sorry, but I am rather clueless about how to deal with Rails, and I need some help about how to use this for redirecting categories and subcategories.

What is the category_id of a (sub)category exactly? Is it the “category slug”, or in the case of a subcategory is it “main category slug/subcategory slug”? Or is it really some number that I need to look up somehow?

An example for redirecting subcategories would be tremendously helpful!

I’ve messed up the first Permalink that I’ve created and I don’t know how to delete it again.