Redirecting Old Forum URLs to New Discourse URLs using permalinks
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
tag_id: to show a tag
user_id: to show a user profile
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:
cd /var/discourse
./launcher enter app
rails c
Permalink.create(url: '/discussion/12345', topic_id: 987)
Discourse will then perform a redirect with http response status code 301 (permanently moved) to the correct url for topic id 12345. 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:
Important behavior for external permalinks on topic URLs
When an external_url permalink is created for a Discourse topic URL (for example /t/some-slug/123) to redirect to an external site, keep in mind:
the original topic should be soft-deleted (not hard-deleted)
the topic should belong to a public category
Why: if the topic is still active, Discourse resolves it normally and permalink lookup is not used.
If the topic is in a private category, permission checks can return 404 before the external permalink redirect is applied.
This is especially relevant for in-app navigation (logged-in users), where routes may be requested as JSON/XHR.
Additional information
To find the id of a subcategory, you can look it up by the slug like this:
Category.find_by_slug('products').id
To delete the permalink for that url, do this:
Permalink.find_by_url("/blah").destroy
There can be only one permalink record per url, so just search by url.