Issue with Service Workers when switching from CRA to Next JS - next.js

So we recently changed our landing page from create-react-app to using Next.js. Our old create-react-app had a basic default service worker registered on users browsers.
Whenever I switched over to our new Next.js website, we realized that users who had been there before would continue to get a crappy cached version of the old website.
I've found a couple of discussions talking about this issue already, but neither solutions seem to be working for me. Those two discussions are:
A website is not refreshing because of caching of service worker, after switching from React to Next.js. How to force update?
https://www.asapdevelopers.com/service-worker-issue-nextjs-framework/
Both of these solutions essentially consist of adding a new service worker file to your Next project with some code to delete the existing service workers. That code looks like
if ("serviceWorker" in navigator) {
window.addEventListener("load", function () {
navigator.serviceWorker.getRegistrations().then((registrations) => {
console.log("--");
for (let registration of registrations) {
registration.unregister().then((bool) => {
console.log("unregister: ", bool);
});
}
if (registrations.length) {
window.location.reload();
}
});
});
}
So i've tried this. My old service worker was served via a file at route OUR_URL/service-worker.js. I added a public directory to my Next project and added a file with the same name and the code above to my project. I then linked this file in my _document.js and can confirm that it runs, as well as I'm able to find it on my Next.js site. The URL for both the new and old files are identical. Unfortunately though, it looks like the issue persists.
In one of the other articles linked above, it also mentions putting this file in the root directory of your Next project. This doesn't make much sense to me as it isn't then being served in anyway that I'm aware of, but I gave this a shot as well, still with no luck.
Anyone have any idea what I might be doing wrong here, or what I could do to fix this? Essentially we just want to force remove any and all old service worker so that our new website loads correctly.

Service workers are (at least generally) registered via the site itself and not automatically found by browsers (at least not yet).
This code (unregistering all service workers for the domain) should go in whatever is being sent from next.js to the browser (e.g. index.js). If you put this on your home page all users going there should have the problem resolved. If you have reason to suspect (based on traffic data) that users have other pages bookmarked you might want to include this in a universal bundle or footer.

Related

Next.js - Incremental Static Regeneration fails (404) on production/Vercel.com

I'm using Next.js + Wordpress/Graphql as headless CMS and deploying to Vercel.
I'm getting a 404 when new posts are created on production (vercel) - not happening locally or when using next build. Strangely, it solves the problem when I redeploy or when I push a new version to the repo and vercel does a fresh build.
I guess this has something to do with the Incremental Static Regeneration?
I had a similar but slightly different issue with a previous Wordpress server that was responding with 429 Too Many Requests. But that was a problem with the first build when all pages were generated and therefore more requests were made. I've switched to another server that seemed to fix the problem and now the problem only occurs after the first build (i.e. when incrementally regenerating pages on request).
Here is one of the problem pages:
https://github.com/garethfoote/blind-ditch/blob/master/pages/projects/%5Bslug%5D.js
Thought this could be the culprit but I'm not getting any remote logs from in console.re:
if (!router.isFallback && !project?.slug) {
console.re.log("404??", project);
return <ErrorPage statusCode={404} />;
}
I'm struggling to work out what is causing this and also how I might further debug this on Vercel. Advice appreciated.
After some digging around I realised that I had not fully understood the use of the fallback key in getStaticPaths.
I assumed ISR would generate new pages that weren't specified in the paths object of getStaticPaths at build time but I know realise that is what fallback: true or fallback: "blocking" does.
https://nextjs.org/docs/basic-features/data-fetching#fallback-true

Sub Domain handling in a Node js application

I have a node.js application hosted on an AWS instance.
The directory structure is user/app/public. index.js lies within app and the public directory holds css, images, js & scripts as well as static HTML files.
Recently I moved from the existing my_application.com/sites to something like sites.my_application.com. Post performing the relevant changes the web pages worked fine except for one web page which for some reason is still hitting the old URL. Rest all work just fine. It is supposed to be a view web page based on Id.
However the CSS and JavaScript and every request from here onwards keeps hitting the previous URL & hence instead of site.my_application/view/id I get my_application/site/view/undefined. Any help on this would be much appreciated!

How do I make a programatically changed site dashboard refresh without restarting the Alfresco/Tomcat service?

I've created a web-script module extension and have verified that it works correctly. What it does is takes the dashboard.xml and related page.component-X-Y.type~id~dashboard.xml files from one site, deletes all dashboard related files on another site then copies the source files to the new site that had them deleted.
pseudo-code
var siteDashboard = getDashboard("site1-shortname");
var siteDashboard = renameShortNames("site1-shortname", "short2-shortname");
deleteDashboard("site2-shortname");
createDashboard("site2-shortname", siteDashboard);
renameShortNames just renames the site id inside the dashboard files to the new site's id.
This all works, I've tested and verified it. My problem is that when I go to http://alfrescosite.com/alfresco/s/remoteadm/get/s/sitestore/alfresco/site-data/pages/site/site2-shortname/dashboard.xml it shows me the new dashboard layout from site1-shortname which is the correct behavior but when I go to the actual site's dashboard within Alfresco share it shows the old site2-shortname dashboard. The only way I can get the new dashboard to show is by restarting the Alfresco/Tomcat service. I've even tried looking at the dashboard with a different browser just in case it was a local caching issue but it's not.
Any ideas on how to make the dashboards refresh to the new layout without having to restart the Alfresco/Tomcat service every time?
I figured out what the problem was. The problem was that I was deleting and recreating the dashboard via Remote API calls to the Alfresco Repository and doing it that way was making the appropriate changes but not telling Alfresco Share of those changes.
The solution was to use a combination the Share root object sitedata to remove the component bindings, delete the components and recreate them through Share so that the changes are automatically updated on the front end without the need for a service restart.
Basically this ended up being a modified version of the code in customise-dashboard.post.json.js inside Alfresco Share

Meteor.js - Template Permissions

This has been asked in similar forms here and here but it seems pretty important, and the framework is under rapid development, so I'm going to raise it again:
Assuming your login page needs to face the public internet, how do you prevent Meteor from sending all of the authenticated user templates to a non-authenticated client?
Example use case: You have some really unique analytics / performance indicators that you want to keep secret. You've built templates to visualize each one. Simply by visiting the login page, Meteor will send any rando the templates which, even unpopulated, disclose a ton of proprietary information.
I've seen two suggestions:
Break admin into a separate app. This doesn't address the issue assuming admin login faces the public internet, unless I'm missing something.
Put the templates in the public folder or equivalent and load them dynamically. This doesn't help either, since the file names will be visible from other templates which will be sent to the client.
The only thing I can think of is to store the template strings in the server folder and have the client call a Meteor.method after login to retrieve and render them. And if you want them to behave like normal client templates, you'd have to muck around with the internal API (e.g., Meteor._def_template).
Is there any more elegant way to do this?
I asked a similar question here:
Segmented Meteor App(s) - loading only half the client or two apps sharing a database
Seems to be a common concern, and I certainly think it's something that should be addressed sometime.
Until then, I'm planning on making a smaller "public" app and sharing the DB with an admin app (possibly in Meteor, possibly in something else, depending on size/data for my admin)
These 2 packages try to address this issue:
https://atmospherejs.com/numtel/publicsources
https://atmospherejs.com/numtel/privatesources
It uses an iron-router plug-in to load your specific files on every route.
The main drawback I see here is that you must change your app structure, as the protected files need to be stored in /public or /private folder.
Also you are supposed to use iron-router.

IIS ASP.NET css/js files not updating until forced page refresh

When we do releases in IIS 7, we deploy new code to the releases directory on the server and then repoint the website in IIS to the new code directory. For example:
Change website directory from C:\company\releases\code-5-17-12 to C:\company\releases\code-5-26-12.
This strategy lets us revert back to a previous release in a worst-case scenario. However, the issue I'm having is that when a user who has been on the site goes to a page, sometimes they might need to explicitly refresh a page in order to get the new updated code.
Is this a caching problem? Is there a way to expire this somehow so users of the site will not be loading up old code from the previous release?
This is a specific problem with javascript files and css files.
The problem with that solution is that your users will always be downloading new css's and js's because <%=DateTime.Now.Ticks%> will be different in every refresh.
A better solution would be to concatenate the version of the application or even the last modified date of the file itself.
I got this to work:
I added a ?v=<%=DateTime.Now.Ticks%> to the end of each css and js filename and this solved it.

Resources