Use axios instead of fetch requests in Workbox - vue.js

Im trying to use workbox to save in cache some stuff for my project, I have already made it to save all my js and css files, fonts, etc, there's one thing missing and that is my project's content that is stored in my pc, Im using axios to fetch my database data, workbox seems to ignore the requests sent from axios, I have made a test and changed one axios request to "fetch" and it worked, it was successfully cached, theres any way to make it work using axios?
This is my code:
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.0/workbox-sw.js");
workbox.routing.registerRoute(
new RegExp('http://localhost/Odr/connections/'),
workbox.strategies.cacheFirst(),
);

There's nothing specific about axios that should prevent its requests from being intercepted by Workbox, or in general, from triggering the fetch handler inside of a service worker. XMLHttpRequests made from client pages do result in the fetch handler being fired.
I would recommend using a debug build of Workbox (which is the default if you're developing on http://localhost) and then opening the JavaScript console when you attempt your axios request. There are debugging messages that should shed light on Workbox's routing logic, including whether a particular request triggering a route or not.

Related

How do dynamic API calls work in Nuxt.js static vs SSR mode?

Even after reading through multiple articles explaining the differences between static and SSR rendering I still don't understand how dynamic API calls work in these different modes.
I know that Nuxt has the fetch and asyncData hooks which are only called once during static generation, but what if I use dynamic HTTP requests inside component methods (e.g. when submitting a form via a POST request)? Does that even work in static sites?
I'm making a site that shows user generated content on most pages, so I have to make GET requests everytime one of those pages is visited to keep the content up to date. Can I do that with a static site or do I have to use SSR / something else? I don't want to use client side rendering (SPA mode) because it's slow and bad for SEO. So what is my best option?
There is actually no difference between either asyncData() or fetch() hooks when you do use target: static (SSG) or target: server (default, SSR).
At least, not in your use-case.
They are used mainly by your hydrated app.
As a reminder, when using either SSG or SSR, your static page will be hydrated and will become an SPA with all the dynamic functionality that we love. This combo of SSG + SPA or SSR + SPA is called an universal app (or isomorphic app).
Both asyncData() and fetch() will be called upon navigation within your client side SPA.
There are also some things happening on the server side, like fetch being called (by default) when you request the server for an SSR built app.
Or the fact that when you generate your app (if using SSG), you can reach some API and generate dynamic routes (useful in the case of a headless CMS + blog combo for example).
For performance reasons and to have a quick build time, you may pass a payload and use it in an asyncData hook in the dynamic route, as explained here
Still, a static Nuxt app, is basically just an app built ahead of time, with no need for a Node.js server, hence why an SSG app can be hosted on Netlify for free (CDN) but and SSR one needs to be hosted on something like Heroku (on a paid VPS).
The main questions to ask yourself here are:
do you need to have some content protected? Like some video courses, private user info etc...already in your Nuxt project (if SSG, disabling the JS will give access to the generated content)
is your first page a login? Is it mandatory to access the rest of the content? Like an admin dashboard (you cannot generate content ahead of time if the data is private, think of Facebook's feed being generated for every account, not feasible and not secure as above)
is my API updating super often and do I need to have some super quick build time (limitation on free tiers essentially)? (SSG will need a re-generation each time the API changes)
If none of those are relevant, you can totally go SSG.
If one of those is important to you, you may consider SSR.
I do recommend trying all of them:
SSR (ssr: true + target: server) with yarn build && yarn start
SSG (ssr: true + target: static) with yarn generate && yarn start
SPA only (ssr: false + either target: static, target: server also work but who wants to pay for an SPA?!) with yarn generate && yarn start
Try to host it on some platforms too, if you want to be sure to understand the differences beyond your local build.
You can use this kind of extension to also double-check the behavior of having JS enabled or not.
I will probably recommend to take the SSG path. Even tho, if your content is always changing you will probably not benefit much from SEO (eg: Twitter or Facebook).
This github answer could maybe help you understand things a bit better (it does have some videos from Atinux).
PS: I did a video about this on the latest Nuxtnation that you can find here.
I use dynamic HTTP requests inside component methods (e.g. when submitting a form via a POST request)? Does that even work in static sites?
The short answer to this question is that yes, it does work. In fact you can have http requests in any life cycle hooks or methods in your code, and they all work fine with static mode too.
Static site generation and ssr mode in Nuxt.js are tools to help you with SEO issues and I will explain the difference with an example.
Imagine you have a blog post page at a url like coolsite.com/blogs with some posts that are coming from a database.
SPA
In this mode, when a user visits the said URL server basically responds with a .js file, then in the client this .js file will be rendered. A Vue instance gets created and when the app reaches the code for the get posts request for example in the created hook, it makes an API call, gets the result and renders the posts to the DOM.
This is not cool for SEO since at the first app load there isn't any content and all search engine web crawlers are better at understanding content as html rather than js.
SSR
In this mode if you use the asyncData hook, when the user requests for the said URL, the server runs the code in the asyncData hook in which you should have your API call for the blog posts. It gets the result, renders it as an html page and sends that back to the user with the content already inside it (the Vue instance still gets created in the client). There is no need for any further request from client to server. Of course you still can have api calls in other methods or hooks.
The drawback here is that you need a certain way for deployment for this to work since the code must run on the server. For example you need node.js web hosting to run your app on the server.
STATIC
This mode is actually a compromise between the last two. It means you can have static web hosting but still make your app better for SEO.
The way it works is simple. You use asyncData again but here, when you are generating your app in your local machine it runs the code inside asyncData, gets the posts, and then renders the proper html for each of your app routes. So when you deploy and the user requests that URL, she/he will get a rendered page just like the one in SSR mode.
But the drawback here is that if you add a post to your database, you need to generate your app in your local machine, and update the required file(s) on your server with newly generated files in order for the user to get the latest content.
Apart from this, any other API call will work just fine since the code required for this is already shipped to the client.
Side note: I used asyncData in my example since this is the hook you should use in page level but fetch is also a Nuxt.js hook that works more or less the same for the component level.

In a Nuxt SSR application, what happens on server and what on client?

I'm on Nuxt 2.13 and building an e-commerce website.
But the are some issues with my server resources, my first load of site takes some time (on route change every thing is ok and fast, just the init is slow).
So i wanna know which parts of my site will be on server and which parts on client browser.
for example as recommended, i use fetch() with axios to get page/component data. as i read the docs it is said on render route it is server-side and on navigation it is client side. so what does that mean? my axios call in fetch() in on server or client? what about my other axios calls in methods to backend?
what i wanna understand is that which parts are on server? and can i make them client-side to save server resources? (I'm afraid with some users the resource usage get too high!!)
That's point of fetch. It's called when it's needed. On server side during initial page load, than all page state is send along with rendered page to client. All following navigation is calling fetch on client side only.
On basic level, you can't care about it.
In reality, to speed up initial load, you may decide to load something always on client. Then you can move it to mounter() hook which is always called only on client side.

Nuxt Async Data - Server is Caching

Im using nuxt with asyncData() to make an axios request to an endpoint. In my build i'm using pre-rendered HTML pages.
I have a set of products on the API end-point and we've just remove most of the products, however they are still showing the full product list.
So I started up my dev server and hit the endpoint and I am seeing the correct updated API list from the endpoint.
So it seems my server is caching the API call. I'm not using a node server, just uploading my pre-rendered html to a server.
It's just I'm trying to isolate the problem and wanted to know if it is a configuration with nuxt.js that will allow me to not cache from the endpoint or is this a strictly a server issue that is causing the API data to be cached?
Or is there a config that I can use in the AXIOS request to always give me a fresh copy?
are you running nuxt with static site generation? in this case nuxt fetches all products from your API at the time it generates the static html. so the nuxt-server does not know anything about the updated api-data.
you could solve this by using a hook and re-building the page every time the api-data changes.
edit: you can find more info in the docs

vue-typeahead says you need to provide a HTTP client

When I try to load vue-typeahead in my browser it says 'you need to provide a http client.' How exactly do I do this?
I am using webpack (the default configuration that comes with laravel 5.5). I have copied the usage example verbatim from here, https://github.com/pespantelis/vue-typeahead, and placed it in its own file, typeahead.vue.
I have then added the file as a vue component as follows:
Vue.component('typeahead', require('./components/admin/shared/typeahead.vue'));
The webpack bundling works fine (npm run dev), and I can see that the component loads in my browser, but when I type a few characters and trigger the http request, I get the error message.
Axios is loaded as part of bootstrapping my Vue instance, but presumably it needs to be passed to the vue-typeahead somehow?
The docs are not very clear.
But look in the samples directory: You have to set the $http property on the Vue prototype.
You have to use a http client that provides an interface compatible with the axios package
https://github.com/pespantelis/vue-typeahead/blob/master/demo/main.js
Looks like the source only uses get(url, params), so if you want to roll your own http client instead of using axios it’s not a ton of work.

Angular2 - How can I add HTTP headers to responses my app sends to the browser?

I'm prototyping an Angular2 app at work. The app should run under some company middleware that expects several Link headers in responses it gets from the angular2 app. Unfortunately, I haven't been able to figure out how to add headers to responses that Angular provides out of the box.
To clarify what I mean - when I send a GET Request directly to my Angular app, it sends back a Text/HTML response that a browser can render into an SPA. I would like to add headers to this response, and can't figure out how. The closest I've found is the discussion here: Angular2 - set headers for every request
This sounds like a duplicate, but having looked through similar questions, I've found how to add headers to Responses I generate explicitly with an HTTP object from the HttpModule, but not how to attach headers to the Responses that Angular creates out-of-the-box. I'd love to use something like an HTTP Interceptor that just attaches headers to every response my app sends out, but it doesn't look like Angular2 will have interceptors until release 4.1.
Edit: Things I've tried:
Adding a provider for Http ResponseOptions in my (main) AppModule that adds headers to responses
This adds the header to all responses I receive from http requests that my app receives from the HttpModule, but doesn't add the header to responses that my app itself sends to outside services.
Edit 2: I misunderstood where my Angular app ends and where the server hosting it begins. Headers like this can be added in the server - for my simple example, I needed to configure the webpack-dev-server. See the accepted answer below.
Web Starter Pack uses webpack-dev-server just as a development hosting platform/Web server for your efforts, but it 's not, in the end, part of your final Angular app proper. You'll eventually serve your Angular app from some other hardened Web server software such as Apache, IIS, etc.
For development purposes, you should be able to configure webpack-dev-server to add custom headers by modifying your webpack.config.js by setting the headers options, per the documentation.
devServer.headers
Adds headers to all requests:
headers: {
"X-Custom-Foo": "bar"
}
For example:
webpack.config.js
...
devServer: {
...
headers: {
"X-Custom-Foo": "bar"
}
...
}
...
Although to actually read the "initial load" headers within your Angular application once it initializes (if that is what you're looking to do) you may need to add your values as [non-httpOnly] cookies, then read them on ngInit().
Source: DevServer Documentation - Header
I don't know the angular2-webpack-starter, but I guess it's just a command line tool easy development of your Angular application. So it just serves your JavaScript, HTML and assets. It's not the application itself. The Angular application runs in a browser and serves as a client of your backend. So you need another server that serves your backend application and all your XHR calls will go to this backend. When you deploy your application, it will probably not run in the angular2-webpack-starter, but in some more advanced HTTP server such as Apache HTTPD or nginx.
Then you need to create a custom Http service (extending angular's own Http service) or XHRBackend. It has access to Request and Response object and can add extra headers there.