Redirect Category to External URL

Is there some native facility for redirecting categories to external URLs?

Customize >> Permalinks apparently does not support this use.

Why would you redirect a category to an external URL?
What’s the point of having the category if you only need a link?

To have the link displayed as a category without going through all the necessary CSS fiddling to do so without it simply being a category.

The community where I’ll be doing this has a few related Discourse installs that each deal with a different set of topics; I want to more cleanly link them together by creating ‘categories’ that link from each site to each other site.

I briefly looked at doing this and it came down to two alternatives.

  1. Create the category with read only permissions for everyone and put the link into the ‘About this category’ page, maybe including a short paragraph why, like an ‘official’ external support site.

  2. Target and overwrite the link href in a theme component.

I was afraid it would come down to that or doing a rewrite at the server level. I think I may just go with the (somewhat questionable) JavaScript option.

So, related issue: I’ve now implemented a redirect (using JavaScript), but… it works only on refresh, which is clearly suboptimal. At any rate, here’s the code I’m using:

$( document ).ready(function() {
	if ( window.location.href === "https://omnifora.com/c/redirect-politifora" ) {
		window.location.replace( "https://politifora.com/" );
	}
});

As should be obvious from the code, Omnifora is the primary site in this network and I am attempting to redirect a Politifora category on Omnifora to Politifora. I’ve already eliminated caching (browser, server, Cloudflare) as a potential culprit. Is there some quirk in Discourse that would cause this redirect not to trigger?

Yes, being a single-page-app the page only loads once, subsequent loads just replace the page contents. There is a page change API you can hook into:

I’m sure this is the right way to accomplish the redirect, but I am not sure how to write the necessary code. I’ve tried the following and neither seems to work:

api.onPageChange((url) => {
	var targeturl = 'https://politifora.com/';
	if ( url === '/c/redirect-politifora' ) {
		$(location).attr('href',targeturl);
	}
});

and

api.onPageChange((url) => {
	if ( url === '/c/redirect-politifora' ) {
		window.location.replace( 'https://politifora.com/' );
	}
});

if you wanted a redirect this is the way to do it

api.onPageChange((url) => {
	if (url.includes('/c/redirect-politifora')) {
		window.location.replace('https://politifora.com/');
	}
});

however this is kinda slow and won’t run until the page has finished loading, which means users will still see the redirect category. i tried a second way, which is using jQuery to replace the links on the index or anywhere else this category appears.

api.onPageChange(() => {
  $(function(){
    $('a[href*="/c/redirect-politifora').attr(
      'href', 'https://politifora.com/'
    ); 
  });
});

with this you don’t need a redirect, because it modifies href attribute of every redirect-politiflora link in place.

Perhaps I’m missing something, but I tried each of those solutions (both imported from an external .js and dropped in as a customization) and was unable to get either one to work.

where are you inserting them, and do you have the correct script tags around them

I tried both the header (using defer) and the footer (via Customize). When inserted via Customize, I had the code surrounded by <script></script> with type="text/discourse-plugin" set.

Update:

The window.location.replace option is currently live on Omnifora. I am using the following code (yes, I have tried a number of different matching options, but none of them seem to work):

Code Dropped into Customize

<script type="text/discourse-plugin" version="0.8.19">
api.onPageChange((url) => {
    if ( url === 'c/redirect/politifora' || url === '/c/redirect-politifora' || url === 'https://omnifora.com/c/redirect-politifora' || url.includes('/c/redirect-politifora') || url.match('/c/redirect/politifora') ) {
        window.location.replace('https://politifora.com/');
    }
});
</script>

Code as Rendered on Page

<script>Discourse._registerPluginCode('0.8.19', function (api) {

    api.onPageChange(function (url) {
        if (url === 'c/redirect/politifora' || url === '/c/redirect-politifora' || url === 'https://omnifora.com/c/redirect-politifora' || url.includes('/c/redirect-politifora') || url.match('/c/redirect/politifora')) {
            window.location.replace('https://politifora.com/');
        }
    });
});</script>

Given the wrapper that Discourse appears to have applied, it seems the code is partially working, but not performing its intended purpose (i.e., redirecting that category to Politifora). The live code (and its failure to function) can both be viewed on the aforementioned site (the target/affected category is currently at the bottom of the category list).

Is there some specific version of the API I should be using for this?

The following script achieves the intended result when added to </head> via Customize:

<script type="text/discourse-plugin" version="0.8.19">
api.onPageChange(() => {
	if ( window.location.href === "https://omnifora.com/c/redirect-politifora" ) {
		window.location.replace( "https://politifora.com/" );
	}
});
</script>

감사합니다! 하위 카테고리 중 하나가 리다이렉트로 작동하도록 설정해야 할 필요가 있었어요. 제 커스터마이즈 코드에 이미 onPageChange() 체크가 포함되어 있거든요(홈페이지에서만 헤더를 표시하는 용도로 사용 중). 그래서 이 방식도 잘 작동할 거고, 사이트의 전체 URL에 하드코딩되어 있지 않아요:

<script type="text/discourse-plugin" version="0.8.19">
api.onPageChange((url) => {
       // 홈페이지에 있는지 확인 
        if (url === "/" || url === homeRoute) {
              // 홈페이지용 커스텀 작업 수행
       } else if ( url=== "/c/redirect-politifora" ) {
             // 카테고리 리다이렉트
             window.location.replace( "https://politifora.com/" );
       } else {
             // 필요한 경우 모든 다른 페이지에서 작업 수행
       }
});
</script>

사실 저는 사용하지 않았습니다. 하위 카테고리 브라우저가 다른 곳으로 리다이렉트되면서 너무 혼란스러운 지연이 발생했거든요. 하지만 어쨌든 새로운 것을 배웠습니다.

페이지가 렌더링된 후에 발화되는 것 같은 api.onPageChange()에 의존하기보다 라우트를 수정하면 이 문제가 덜 발생할 수 있습니다.

Redirect an existing route in a theme component 를 참조하세요.