Adding redirects in Next.js when using a CMS - next.js

I want to add a redirect functionality to an app in NextJS that fetches all content from a CMS (Contentful). In that process, I am thinking on two different approaches regarding the implementation in NextJS and content modelling.
I would like to better understand whether Approach I is doable and also a good practice, or if I should go for a different way, possibly approach II.
Approach I:
The actual situation I am trying to work with regarding content modelling:
Page
Url
Content
Redirects
From url
To url
Some Page content types will potentially have in the future some redirects, which means that for each redirect, a new Redirect content will be created.
I wrote a helper method that calls the CMS API and brings the content as a Redirects array, expecting that I could use that data to populate the redirects array returned inside the next.config.mjs file.
next.config.mjs fetchRedirects call screenshot(from inside redirects() )
In this approach I am finding some troubles, since I get the following error when running npm dev or trying to build:
node:internal/errors:490
ErrorCaptureStackTrace(err);
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/user/Dev/my-web/apps/api-calls/graphql/redirects' imported from /Users/user/Dev/DFDS/my-web/apps/dfds-unified-web/next.config.mjs
at new NodeError (node:internal/errors:399:5)
at finalizeResolution (node:internal/modules/esm/resolve:231:11)
at moduleResolve (node:internal/modules/esm/resolve:850:10)
at defaultResolve (node:internal/modules/esm/resolve:1058:11)
at nextResolve (node:internal/modules/esm/loader:164:28)
at ESMLoader.resolve (node:internal/modules/esm/loader:838:30)
at ESMLoader.getModuleJob (node:internal/modules/esm/loader:419:18)
at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:77:40)
at link (node:internal/modules/esm/module_job:76:36) {
code: 'ERR_MODULE_NOT_FOUND'
}
Node.js v19.4.0
I can´t find proper documentation on this approach, and it is not clear to me why the app is crashing, since the import path to fetchRedirects is correctly referenced. I have tested the fetchRedirects method by calling it in the getStaticProps function inside the pages slug and it is working properly.
Hardcoding the redirects array inside next.config.mjs is not an option, since I would like to come up with a scalable solution to my problem.
Approach II
Page
Url
Redirect
Content
A second approach I am considering is having a Redirect content type inside the Page content type. By this means, I could return a redirect element from the getStaticProps function, together with the props for each of the pages, and then write some logic to redirect in case that the property is found.
I haven´t tried this last approach yet, but I understand that it is also possible, and I was also able to find some more references on how to do it. But I still would like to go for approach I if possible, since I would like to learn from it, or confirm that it is either inviable or not good practice.
I would highly appreciate any recomendation and possibly documentation that I am not finding at the moment.
Thank you for your time.
Have a nice day!

Related

how to avoid HTTP status code 404 on nuxt error.vue

Using Nuxt, we need to be able to render pseudo-routes, like this:
https://server.com/non-existent-route
Where "non-existent-route" is a dynamic path.
Normally, this would render error.vue. This is fine, as we've subverting the use of this page to render what we want. But... we just discovered that Nuxt is sending a 404 anyway! This only happens when the page is first loaded in a fresh tab, for some reason. This is very bad.
So, we need a way to avoid HTTP status 404 in some cases.
We found this:
https://medium.com/finn-no/hacking-nuxts-404-logic-for-maximum-awesome-and-easy-proxying-e4efaeb03d66
which is actually not as helpful as we had hoped it would be, as it simply provides a way to proxy another URL, sending us back to the same problem.
We suspect there might be some middleware solution to this problem... but have not been able to come up with it.
Turns out the answer was right here all long:
https://nuxtjs.org/guide/routing#dynamic-nested-routes
Rather disappointing that nobody suggested this extremely simple solution.

Razor pages "asp-page" not linking to specified location, instead linking to current page

I'm seeing some unexpected (to me) behavior when using asp-page in my asp.net Razor Pages application. I have a folder structure like this:
Manage
Index
NewAccount
On the NewAccount page, I want to have a link back to the manage account page, /Manage/Index. I'd expect the following code to do this:
<p><a asp-page="/Manage/Index" asp-route-accountId="#Model.AccountId">Back to account view</a></p>
Instead of linking to the /Manage/Index page though, it's linking me back to /Manage/NewAccount! This makes absolutely no sense to me.
I've tried quite a few values for asp-page.
/Manage/Index: Loads Manage/NewAccount as described
/Index: Loads /Index, which is what I'd expect
./Index: Loads /Index
/Manage: Routes to /Manage/NewAccount
I know I could get this working using regular HTML code. But I'm trying to do this using canonical asp.net syntax. Plus I'd really like to use asp-route to pass query parameters, which you can't use with href.
I'm sure the issue is obvious to those of you who know razor pages better than I. I'd love an explanation of why /Manage/Index doesn't work as well, if someone knows. Thanks!

Redirecting to .aspx in a different domain

Okay, I'm dealing with a problem hear.
I'm building landing pages for my company.
The main website works with a .aspx form to retrieve car data (from for example licenseplates).
Now we've set up some new relevant domain names to use for some of the landing pages.
The problem now is, that when on those pages I type in licenseplate and click search, it fails doing so.
Since it tries to find the .aspx form on the landing page domain url.
For example:
Main site: www.mysite.com/category.aspx?k=80zbfk (refered to when the licenseplate is typed in.)
Landing page: www.mysite2.com/category.aspx?k=80zbfk (were it refers to on the landing page)
No the second one should refer to the first one. But I can't seem to find a way to do so.
I don't have acces to the .aspx files since they're in control of a external company.
Is there any way to fix this? To refer the landing page to the .aspx from the main site?
Or do I have to contact the webcompany to ask for the files so I can copy them to the other domain?
Thanks in advance!
It sounds like you want to be using absolute links rather than relative.
An absolute link includes the host and path of the target url, whereas a relative one contains only the path and lets the browser infer the host (via the url being visited).
For example, if you were editing the HTML of a page here on Stack Overflow, the absolute link to this question would look something like this,
http://stackoverflow.com/questions/26379795/redirecting-to-aspx-in-a-different-domain
While the relative one would look like this,
/questions/26379795/redirecting-to-aspx-in-a-different-domain
In the case of the latter one, the browser would be left to assume based on context that you wanted to go to that path on http://stackoverflow.com/. There's a bit more to it, and variations on that syntax exist. But that's the gist of it.
So, getting back to your question, yes. You will probably have to update the ASPX pages. Relative links are best practice in most cases, which explains why they were used in your code, but you've got an exception. It's probably going to be easiest to just go through and change whatever links you need, to point to the main domain. But for what it's worth, that should be a relatively easy fix, once you get the files.
Alternatively, you could set up a rewrite rule or redirection policy on your landing page servers to automatically 301 redirect any requests that contain search information off to the main server, but that's definitely a workaround approach, and there will be a performance hit in doing so. The one and only advantage that I can imagine to doing that is that you wouldn't need to get the pages from the third party, but it sounds like that wouldn't be a bad idea to do anyway.

How to serve different cached versions of a page depending on a cookie in Drupal?

The task is relatively straightforward:
A Drupal website displays a list of articles with thumbnails. Some visitors would like to view it without images by clicking on a button/link and have that preference saved.
e.g. http://patterntap.com/collections/index/
The problem is all visitors are anonymous and given certain traffic, page cache is enabled.
My idea was to use some simple JavaScript to set a cookie, refresh the page and depending on the cookie values (or its presence/absence) display or hide the images.
Except Drupal serves cached pages quite early and the only quick way to modify the cached version that I could find is by hacking includes/bootstrap.inc and add a custom class to the body classes then hide the images with css.
A very wrong approach, I know. But I wonder if there is a way to save different versions of a page and serve the correct version?
Edit:
need to keep the same uri
the js to show/hide the images without reload and set the cookie is already in place
hook_boot() is not really called for cached pages, so can't do it via custom module
.htaccess mods?
Edit/solution:
In the end went with Rimian's suggestion. But it is possible to accomplish the task using our own cache.inc implementation as seen in the Mobile Tools module. Specifically, by extending cache.inc and updating settings.php to include
$conf['page_cache_fastpath'] = FALSE;
$conf['cache_inc'] = 'path/to/my/module/my_module_cache.inc';
So let me get this right. You wanna hide some images on a cached page if the user chooses to?
Why don't you write some jQuery or javascript and load that into your cached page with all the rest of the document?
Then, the client/browser would decide to run your script and hide images depending on some parameters you passed along with the request to that page or in the cookie? The script gets cached and only runs when you call it.
If you were hacking the bootstrap for something like that you'd really need to be rethinking what you were doing. Crazy! :)
Also take a look at cache_get and cache_set:
http://api.drupal.org/api/drupal/includes--cache.inc/6
I'm not sure I 100% understand what you are trying to do but here are my thoughts. One of your root problems is that you are trying to access what is essentially different content at the same uri.
If this is truly what you want to do, then Rimian's suggestion of checking out chache_get and chache_set may be worthwhile.
Personally, it seems cleaner to me to have your "with thumbnails" and "without thumbnails" be accessed via different uri's. Depending on exactly what you are wanting to accomplish, a GET variable my be an even better way to go. With either of these two options you would hide or show your thumbnails at the theme layer. Pages with different paths or get variables would get cached separately.
If you want the visitor to be able to switch views without a page reload, then jQuery and a cookie would probably suite your needs. This wouldn't require a page reload and switching back and forth would be quite simple.

iframed ASP actions trouble

This is actually a follow up on my previous question (link)
I've created the HttpHandler and it works fine for now, I'll add flexibility by using the querystring and session to point the post I'm making in the right direction.
The next question is as follows.
Now that I have the old page iframed as it should be, there's still the trouble of handling the postbacks (or actions) these pages trigger.
Every button action (asp form post) refers to a page that is not there (it's on the other server from which I am importing functionality).
I've tried using a url mapping to the other server but I get an error that tells me the external link is not a valid virtual directory. Hence I discarded this option.
I there anyway to keep functionality going inside the iframe?
please do ask clarification if you need it.
I got a solution from a colleague.
before passing the response string to the Iframe from the handler I use a string.replace to adjust the urls in the old site. This way they point to the old site and everything works again :)

Resources