Nuxt How to set baseURL in dev or production - vue.js

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>

Related

Specify config file in nuxt 3

I have a Nuxt 3 application (3.0.0-rc.13) generating a static website, and have to deploy to two locations:
Firebase hosting
Amazon S3 bucket
Hosting on Firebase needs a baseUrl of /, and Amazon needs a different baseUrl (/2223/). This can be configured in nuxt config, however I cannot find an cli option to specify which config file to use.
I have tried these, but they just pick the default nuxt.config.ts.
nuxt generate -c nuxt.config.amazon.ts
nuxt generate --config-file nuxt.config.amazon.ts
I found this issue that added support to it for Nuxt 2, but I cannot find anything about it for Nuxt 3. Am I missing something or is it just not supported at all?
Thanks for the solution #kissu
If anyone faces the same problem, here is how I implemented it:
package.json scripts:
"generate": "cross-env DEPLOY_TARGET=default nuxt generate",
"generate:amazon": "cross-env DEPLOY_TARGET=amazon nuxt generate",
nuxt.config.ts
const getBaseUrl = () => {
const environment = process.env.DEPLOY_TARGET;
switch (environment) {
case "amazon":
return "/2223/";
default:
return "/";
}
};
export default defineNuxtConfig({
app: {
baseURL: getBaseUrl(),
},
});

Vue js how to use route from index.html to docs folder

I am new to Vue js, I am building a website using Vue js where I have a home page and docs folder which contains a lot of documents written and save in a .md file.
Now How I can on the navbar click redirect from my route.js page to docs .md files. Below is my folder structure.
I want to serve my homepage from main.js which is created using vue.js, and docs folder containing markdown files. Inside the docs folder have .vuepress with config.js which was configured to load index.md as the home page.
- docs
- guide
- index.md
- src
- components
- route.js
- vue.config.js
- main.js
Package.json
{
"scripts": {
"docs:build": "vuepress build docs",
"docs:dev": "vuepress dev docs",
"dev": "vuepress dev docs",
"build": "vuepress build docs",
"start": "vue-cli-service serve"
},
}
UPDATE: There are a few issues in your new code:
The app site uses Vue 2, which requires VuePress 1.x, but you have VuePress 2.x installed. If you want the docs and app source in the same project root with different NPM dependencies, you'd need something like a monorepo. To otherwise share NPM dependencies, you'll have to upgrade your app project to Vue 3 or downgrade VuePress. For the sake of example, install VuePress 1.x instead:
npm i -D vuepress#1
The VuePress port is not configured, so it starts at 8080 (until a free port is found). The docs link in your app is hard-coded to port 3000, so your VuePress should be configured to start there:
// docs/.vuepress/config.js
module.exports = {
port: 3000
}
The VuePress base URL is not configured, while your app assumes a base of /docs. Update your VuePress config to set the base URL acccordingly:
// docs/.vuepress/config.js
module.exports = {
base: '/docs/'
}
See GitHub PR
Answer to original question:
VuePress setup
Install vuepress in your project:
$ npm i -D vuepress # if using #vue/cli#4
$ npm i -D vuepress#next # if using #vue/cli#5
Add NPM scripts for Vuepress:
// package.json
{
"scripts": {
"docs:build": "vuepress build docs",
"docs:dev": "vuepress dev docs"
}
}
Create docs/.vuepress/config.js, and export a config object:
a. dest - Output the docs to your app's build output directory (dist for Vue CLI scaffolded projects).
b. base - Set the base URL so that it matches the intended destination on the server (e.g., set base URL to docs if deploying docs to https://example.com/docs/).
c. port - Set the port of the VuePress dev server (we'll configure Vue CLI's dev server to point there later).
d. themeConfig.nav - Set the top navbar links.
// docs/.vuepress/config.js
module.exports = {
dest: 'dist/docs',
title: 'My Project Docs',
base: '/docs/',
port: 3000,
themeConfig: {
nav: [
{
text: 'Guide',
link: '/guide/',
},
{
text: 'Main Project',
link: 'http://localhost:8080'
}
],
}
}
Add a docs link to your app's navbar (e.g., in App.vue):
<nav>
Docs 👈
<router-link to="/">Home</router-link>
...
</nav>
Create docs/README.md with the following contents:
# Hello World
Building
Build your app before the docs (especially if the app's build command deletes the output directory beforehand, as it does with Vue CLI):
$ npm run build
$ npm run docs:build
Development
If using Vue CLI, configure the dev server to redirect /docs to the VuePress dev server:
Configure Vue CLI's devServer.before:
// vue.config.js
module.exports = {
devServer: {
before: app => {
// point `/docs` to VuePress dev server, configured above
app.get('/docs', (req, res) => {
res.redirect('http://localhost:3000/docs')
})
}
}
}
Start the app's server and the docs server:
$ npm run serve
$ npm run docs:dev
You could add the the docs folder into the public directory, then link to /docs/guide/...

Nuxt static generated page and axios post

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.

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.

rendering css by environment

I'm looking to switch to webpack on an asp.net mvc website and there's 3 different environments of this website and each environment has their own color scheme (so people know what environment they're on) so I need a way to tell webpack which css file to load and when, but not sure how to go about that.
the end result is:
/asset/styles/style.dev.css
/asset/styles/style.debug.css
/asset/styles/style.prod.css
Update
For example you have a certain theme enabled by default and you have a theme switcher control (layout page) which raises events client-side using JavaScript.
In your entry script you can attach to the changed event of the theme switcher control and do:
Dummy code: Index.js
function changedEventHandler(){
var selectedTheme = $(this).selectedValue;
switch (selectedTheme) {
case "themeA":
require("themeA")
break;
case "themeB":
require("themeB")
break;
default:
require("defaultTheme")
}
}
webpack.config.js
resolve: {
alias: {
"theme$": path.resolve(theme),
"themeA$": path.resolve("./src/css/themeA.css"),
"themeB$": path.resolve("./src/css/themeB.css"),
...
If you want three different builds each with a different theme, you can do the following:
If you want a build with themeA run: npm run themeA
If you want a build with themeB run: npm run themeB
package.json
"scripts": {
"themeA": "webpack --env.theme=themeA --mode development",
"themeB": "webpack --env.theme=themeB --mode development",
webpack.config.js
module.exports = (env) => {
var theme = "";
if (env.theme) {
theme = "./src/css/" + env.theme + ".css"
}
console.log(path.resolve(theme));
return {
entry: './src/index.js',
output: {
path: distfolder,
filename: 'bundle.js'
},
resolve: {
alias: {
"theme$": path.resolve(theme)
}
},
...
..
.
In your entry point you can do:
index.js
import "theme"