I recently developed and published my first large angular project (I am still relatively new to angular). For better SEO I decided to look into static prerendering using both Scully and Angular Universal, both have one critical issue, so google search console & Bing webmaster refuses to rank most of my routes because of Redirect issues (301 redirect).
So what happens is that, after the page is prerendered the urls is adding an extra slash "/" at the end, then after few seconds angular starts and makes a redirected javascript to the correct page.
the prerender page will make the url like
https://www.mywebsite.com/page1/
then after some time redirects to
https://www.mywebsite.com/page1
the first url is the one prerendered
google search console & Bing webmaster consider both of these routes as redirects and are therefore not indexed, when the one without "/" is visited, slash is first added and then removed (therefore a redirect ) and similarly when the one with "/" is visited it is redirected to remove the slash. Prerendering is supposed to help in SEO but it is instead hurting SEO, I’ve checked and these are indeed 301 redirects, Am I doing something wrong here? I searched about this issue all around the internet but found no solution. Can someone please help me with this.
As you can see in the screenshot most of my pages are not indexed with the reason given as pages with redirect or redirect error
3
Answers
I finally figured it out
Short answer: Because of the way angular universal pre-rendering works you can't remove "/" at the end for the pre-rendered pages, Your only solution is to make all your routes end with "/" by default, so when angular starts and is redirecting it will also redirect to the exact same url hence not counting as a redirect
Long answer:
Why is this happening?
First we need to understand why is this happening in the first place. So the way angular pre-rendering works is that for each route a directory/folder by the name of that route is generated with an "index.html" file inside. So lets say if I have a route "mywebsite.net/page1", angular universal will generate a directory "page1" with an index.html file inside containing the html code of that page. In both nginx and apache servers a directory is represented by a "/" relative to the base directory. So if the server want to access index.html file inside of that page1 folder the path would be represented as "/page1/", notice the trailing slash in the end meaning we are inside the page1 directory, alternatively if we had a "page1.html" file at the root directory that would be represented as "/page1" but that's not how angular universal generates it's pages, as mentioned above it generates directories with index.html files inside.
Why is there a 301 redirect
So when we first visit any route let's say "/page1", our server goes inside the page1 directory and opens up index.html file inside, and because it is a directory and not a file in the root directory it adds "/" in the end and once that index.html file is rendered the angular script runs it redirect you to the route you have defined in your angular routes, if it is without a "/" it will redirect to it, hence removing the slash. This is why slash is added and then removed
Solution
The solution is to make all your routes end with a trailing slash by default. In you every module you will define your routes as
notice "/." at then end of the path and in your
and in your main.ts you can add some logic to add a trailing slash to the links without one. something like this
Doing all this fixes the redirect issue.
I answered this once but @Dharman felt this was a duplicate answer but this is a different issue because it involves Scully and an Apache Server. The other one I answered had differences on this front.
If anyone is looking for answers for this you can check out my answer here and get some inspiration for the differences this question provides since moderators will delete it if I give you helpful hints here:
https://stackoverflow.com/a/73835009/5832236
I had the same issue with redirects
301
.Well, the redirects are initiated by a server, therefore it might be a better solution to tweak the server configuration instead of adapting the code for unusual/undesired behavior.
In my case, it is
scully
andnginx
, which the classical standard configurationThis means that the server is looking for
a file to serve as an exact match
$uri
.If not found, it looks if a folder exists with this exact name
$uri/
.If the folder exists, the server performs an internal redirect into it and serves the
index.html
which is located inside it (if it is there).If none is found, it performs an internal redirect to
/index.html
in the root folder.This is exactly the case for pre-rendered angular apps, where for each route a pre-renderer creates a folder with the corresponding name and places an
index.html
file inside it.In order to serve the
index.html
file from a requested route directly, it is sufficient to modify thelocation
configuration as followsHere server responds with an exact match
$uri
, and if not found, with a fileindex.html
in the specified folder$uri
without a redirect.I guess a similar configuration can be made for another type of server.