Nuxt static generated page and axios post - vue.js

I have a Nuxt project. Everything is OK when I generate a static page.
However, I need to send a POST request to the other server.
I tried to use both a proxy in nuxt.config.js and just direct query, but after deploy to the ngnix eventually, nothing works.
Please help.
UPDATE. Steps to reproduce.
Create Nuxt App including axios and proxy
Configure your proxy for other webservice:
proxy: {
'/api': {
target: 'http://example.com:9000',
pathRewrite: {
'^/api': '/',
},
},
changeOrigin: true,
},
call this service somewhere in the code:
const result = await this.$axios.post('/api/email/subscribe', {email: email})
run "yarn dev" and test the service. It works locally properly.
run 'nuxt generate' and deploy the static code hosting service, for example, hosting.com
run your page which calls the above-mentioned service.
As a result, instead of making POST call to the hosting.com/api/email/subscribe, it calls localhost:3000/api/email/subscribe.

Be sure to install the nuxt versions of axios and proxy in your project #nuxt/axios and #nuxtjs/proxy
after that in your nuxt.config.js add axios as module plus this options for axios and proxy:
modules: [
// Doc: https://axios.nuxtjs.org/usage
'#nuxtjs/axios',
//more modules if you need
],
/*
** Axios module configuration
*/
axios: {
proxy: true,
// See https://github.com/nuxt-community/axios-module#options
},
proxy: {
'/api/': {
target: process.env.AXIOS_SERVER, // I use .env files for the variables
pathRewrite: { '^/api/': '' }, //this should be your bug
},
},
now you can use axios in any part of the code like this
const result = await this.$axios.post('/api/email/subscribe', {email: email})
it will internally resolve to AXIOS_SERVER/email/subscribe without cause cors issues.
EXTRA: test enviroments in local using multiples .env files
you can configure .env for dev and .env.prod for production, after that in local you can use yarn build && yarn start for test your app with your production enviroment. You only need add this at the top of your nuxt.config.js file
const fs = require('fs')
const path = require('path')
if (process.env.NODE_ENV === 'production' && fs.existsSync('.env.prod')) {
require('dotenv').config({ path: path.join(__dirname, `.env.prod`) })
} else {
require('dotenv').config()
}

By definition on the Nuxt docs page what nuxt generate does is: Build the application and generate every route as a HTML file (used for static hosting).
Therefore, using proxy is out of question here. Take note that you path is not even being rewritten.
And probably the result you're looking for is not hosting.com/api/email/subscribe (wit /api), but hosting.com/email/subscribe.
Nevertheless, if you use nginx then I don't think you should use Nuxt's proxy option. Nginx is built just for that so point your API calls there and in nginx config file just declare where it should point further.

Related

vuejs pwa prevent using cache when requesting /api/ routes

i had created a Vuejs project with PWA support but when i am building its production build it always using cached version of api requests i want to prevent it from using cache for api requests or change its policy from being to cacheFirst to NetworkFirst for api i found a i had changed vue.config.js to prevent cacheing but its not working
pwa: {
workboxOptions: {
exclude: [/.*\/api\//,],
},
},
any help on how i can either prevent cache on api routes or set networkFirst policy
exclude option only works for excluding precaching assets, which is what vue generates at build time, not api requests at run time.
It seems the Cache-Control problem of the api server, but if you do not have access to that server, you can config NetworkFirst policy runtimeCaching:
module.exports = {
pwa: {
workboxOptions: {
runtimeCaching: [{
urlPattern: new RegExp('^https://api.example.com/path'),
handler: 'NetworkFirst',
}]
}
}
};

How to set url in vue for a external backend api and a devserver api

I'm setting up an app using Vue, and want to create an API Service where on production should point to api.domain.com.br and on dev should point to 127.0.0.1:1337.
My API is using axios to make requests like so:
axios.post('/api/v2/plan', plan)
My vue.config.js has a this proxy solution:
devServer: {
proxy: {
'/api': {
target: 'http://127.0.0.1:1337',
ws: true,
changeOrigin: true
},
}
},
I could create a service from axios and import it on api:
import axios from 'axios';
const client = axios.create({
baseURL: 'https://api.domain.com.br'
});
export default client;
But then it wont work with dev proxy set on vue.config.js
synthesis:
App on production is at app.domain.com.br
Api on production is at api.domain.com.br
App on dev is at 127.0.0.1:8080
Api on dev is at 127.0.0.1:1337
When i build this app, it should use api.domain.com.br on axios calls.
I would use an env file with a base url variable
.env.development
VUE_APP_BASE_URL=http://127.0.0.1:1337
.env.production
VUE_APP_BASE_URL=https://api.domain.com.br
then in your axios
const client = axios.create({
baseURL: process.env.VUE_APP_BASE_URL
});
.env.development is automatically loaded for the command vue-cli-service serve
.env.production is automatically loaded for the command vue-cli-service build
You can also use local .env files which are gitignored by default in vue cli projects. See vue's documentation for more info.

Using browser-sync with vue js and framework7

I have created a PWA using vue js 2.0 and framework7 and also use Webpack for bundling. I want to use browser-sync to share my project.
I used this config in my webpack.confg file :
new BrowserSyncPlugin({
// browse to http://localhost:3000/ during development,
// ./public directory is being served
host: 'localhost,
port: 3000,
server: { baseDir: ['src'] }
}),
In src/ I have my basic files like index.html, app.vue, app.js.
After using npm run dev command I see this result :
[Browsersync] Access URLs:
----------------------------------
Local: http://localhost:3000
External: http://192.168.1.118::3000
----------------------------------
UI: http://localhost:3001
UI External: http://localhost:3001
----------------------------------
[Browsersync] Serving files from: src
After this, localhost:3000 open in my browser and say browsersync: connected but it have showed me a blank page.
Also after I enter website path (http://localhost:3000/en/#!/login) in browser, it showed me Cannot Get /en Error. What is the problem?
Any help will greatly appreciated.
Based on your comment, looks like you are also using webpack-dev-server. In that case you can proxy to it:
const BrowserSyncPlugin = require('browser-sync-webpack-plugin')
module.exports = {
// ...
devServer: {
port: 3100
}
// ...
plugins: [
new BrowserSyncPlugin(
// BrowserSync options
{
// browse to http://localhost:3000/ during development
host: 'localhost',
port: 3000,
// proxy the Webpack Dev Server endpoint
// (which should be serving on http://localhost:3100/)
// through BrowserSync
proxy: 'http://localhost:3100/'
},
// plugin options
{
// prevent BrowserSync from reloading the page
// and let Webpack Dev Server take care of this
reload: false
}
)
]
}

Nuxt How to set baseURL in dev or production

This seems like a simple Nuxt question, but I just can't figure it out.
When running "NPM run dev" I want to set the Axios baseURL to "localhost/api" and when running from the dist folder after "NPM run generate" I want the baseURL to be "/api".
Is there a simple solution?
This is the way to do it through the nuxt.config.js:
let development = process.env.NODE_ENV !== 'production'
module.exports = {
axios: {
baseURL: development ? 'http://localhost:3001/api' : 'https://domain/api'
},
modules: [
'#nuxtjs/axios'
],
}
As you can see, you should specify full URL of your backend, including domain (except SPA-only mode).
And don't forget to install #nuxtjs/axios as dependency to try the example.
you can also set api from outside (eg package.json scripts) by env variable
my package.json fragment (there is additional complexity when browser uses different
api url then server side rendering, still all is supported by Nuxt itself with variables API_URL_BROWSER and API_URL)
"scripts": {
"dev-prodapi": "API_URL=https://kairly.com/api nuxt",
"dev": "API_URL=http://localhost:8000/api nuxt",
"dev-spa-prodapi": "API_URL=https://kairly.com/api nuxt --spa",
"dev-spa": "API_URL=http://localhost:8000/api nuxt --spa",
"build": "API_URL_BROWSER=https://kairly.com/api API_URL=https://internal-apihost/api/ nuxt build --modern=server",
"start": "API_URL_BROWSER=https://kairly.com/api API_URL=https://internal-apihost/api/ nuxt start --modern=server",
and using no axios section in nuxt config at all.
In Nuxt 3 we can use a .env file. Here's the doc.
# .env
API_URL=http://localhost:8080/api
// nuxt.config
export default defineNuxtConfig({
runtimeConfig: {
// Private keys are only available on the server
apiSecret: '123',
// Public keys that are exposed to the client
public: {
apiUrl: process.env.API_URL
}
}
})
// MyComponent.vue
<script setup>
const config = useRuntimeConfig()
console.log(config.public.apiUrl)
</script>

VueJS + Webpack Dev Server not able to hot reload url subpaths

My application runs on the subdirectory http://localhost:8080/admin_suffix
suffix is a ENV variable which I can change and define in a .env file.
Once i run the webpack dev server, accessing http://localhost:8080/admin_suffix works.
Clicking on the hyperlinks in the SPA which points other subpaths works too. For example, I can navigate to http://localhost:8080/admin_suffix/subdirectory
However, when i hit reload on http://localhost:8080/admin_suffix/subdirectory, i will get an error "Cannot GET /admin_suffix/subdirectory"
I also cannot enter the subpath into the browser directly to load the page. Only ``http://localhost:8080/admin_suffix` works.
My configuration are as follows:
webpack.base.config.js:
entry: {
main: './src/main',
vendors: './src/vendors'
},
devServer: {
host: '0.0.0.0',
disableHostCheck: true
},
output: {
path: path.join(__dirname, '../dist')
}
webpack.dev.config.js:
module.exports = merge(webpackBaseConfig, {
output: {
publicPath: '/',
filename: '[name].js',
chunkFilename: '[name].chunk.js'
}
});
src/main.js:
const RouterConfig = {
mode: 'history',
routes: Routers,
base: '/admin_suffix/'
}
Enable devServer.historyApiFallback in webpack.base.config.js:
devServer: {
historyApiFallback: true,
// ...
},
This configures webpack-dev-server to fallback to index.html when the route is not found (404).
The Vue app and router are initialized from the main page (index.html), so refreshing the page while on a subroute would normally result in a 404 because the router would not have been setup yet. However, the fallback configuration mentioned above would result in the index.html being served instead, allowing the router to be setup and the subroute to subsequently complete.