How to redirect an existing Disourse route in a theme component

To redirect an existing Discourse route in a theme component, you can use api.modifyClass to modify the route class.

More information can be found in the Ember documentation on routing redirection. Here’s an example:

<script type="text/discourse-plugin" version="0.8"> 
    // Modify the tag route. 
    api.modifyClass('route:tag-show', {
    	afterModel: function(tag, transition) {
    	    this._super(tag, transition);
            // If it's Sunday, redirect to the topic with id 20.
            if (today.getDay() == 6) {
                this.replaceWith("/t/20");
            }
        }
    }
</script>

If you need to load data to decide where or whether to redirect, you need to have your route hook return a promise, as discussed in the Ember documentation on asynchronous routing. Here’s an example:

<script type="text/discourse-plugin" version="0.8">
    const ajax = require('discourse/lib/ajax').ajax;

    api.modifyClass('route:tag-show', {
    	afterModel: function(tag, transition) {
            // It seems to matter that this comes first.
    	    this._super(tag, transition);

            // Redirect to the first open topic that is tagged with both the route tag and the 'canonical' tag.     	    
            var path = `/tags/intersection/canonical/${tag.id}.json`;
            const context = this;
            return ajax(path).then(function(result){
                var topics = result.topic_list.topics.filter(function(topic) { 
                   return !topic.closed ;
                });
        	    if (topics && topics.length > 0) {
        	        var topic = topics[0];
                        // You need to consider the case where the destination is the same as the origin.
                        // You could cancel the transition, but here we allow it to proceed without a redirect.
        	        if (!transition.from || transition.from.parent.name != 'topic' || transition.from.parent.params.id != topic.id) {
        	          context.replaceWith("/t/" + topic.id);
        	        }
        	    }
    	    })
    	    // Catch any problems so that the (non-redirected) route can proceed as a fallback. 
    	    .catch(function() {
    	        console.log('Error loading topics by ajax in tag show route afterModel hook.');
    	    });
    	},
    });
</script>
4 Likes