axios-module
axios-module copied to clipboard
not work with nuxt 3
not work with nuxt 3
Hello, same pb with nuxt3
Cannot restart nuxt: options is not defined
i got same problem
we can try but same problem again
I got a same problem. I tryed to add this setting to my nuxt config. This solved this problem but a new error occurred on the client side.
modules: [
"@nuxtjs/axios"
],
axios: {
baseURL: 'http://localhost:4000',
options: {
headers: {}
}
},
I think "@nuxtjs/axios" is not required. because useFetch instead it. although useFetch has some bugs.
@xiongsongsong
Thank you. I didn't know that it is possible to use useFetch
.
I'll watch for that some bug. π
@xiongsongsong Thank you. I didn't know that it is possible to use
useFetch
. I'll watch for that some bug. π
There seems to be no other better solution
I set it as below and updated nuxt3(3.0.0-27247485.fb4359e) and it worked.
modules: [
['@nuxtjs/axios',{proxyHeaders:false}],
],
The reason I set proxyHeaders to false is because I get an error that serializer is not defined
https://github.com/nuxt-community/axios-module/blob/main/lib/plugin.js#L210-L219
However, I don't think this has solved it.
Cannot restart nuxt: serialize is not defined
Same problem
You can temporary turn off proxyHeaders in nuxt.config.ts
modules: ["@nuxtjs/axios"],
axios: {
proxyHeaders: false,
},
In my case I needed to add baseUrl config to get it to work
publicRuntimeConfig: {
axios: {
baseURL: '......'
}
},
modules: [
['@nuxtjs/axios',{proxyHeaders:false}]
],
I get an error like this, I don't know how to solve it.
Nuxt version v3.0.0-27324955.23397e6
I get an error like this, I don't know how to solve it.
Nuxt version v3.0.0-27324955.23397e6
please check my answer above, you need to provide baseURL
I get an error like this, I don't know how to solve it. Nuxt version v3.0.0-27324955.23397e6
please check my answer above, you need to provide baseURL
I've add the baseURL to the config, but still got the error
modules: ["@nuxtjs/axios", {proxyHeaders: false}], publicRuntimeConfig: { axios: { baseURL: process.env.AXIOS_BASE_URL || 'http://localhost:3000/api' } }
@imamnf
Did you include the following commit?
https://github.com/nuxt-community/axios-module/pull/516/commits/c539548728c11aa1a1f64e6fbc127165c09a9ada
Without this commit, even the client will try to get the baseURL on the server side. Because process.browser is returning false.
https://github.com/nuxt-community/axios-module/blob/a99b56c11166cc1b0cde89fe5982c853ced17c57/lib/plugin.js#L196-L198
@imamnf
Did you include the following commit?
Without this commit, even the client will try to get the baseURL on the server side. Because process.browser is returning false.
https://github.com/nuxt-community/axios-module/blob/a99b56c11166cc1b0cde89fe5982c853ced17c57/lib/plugin.js#L196-L198
how to include that? I don't know where the file is
Sorry.
This hasn't been released yet :bow:
In my case I am using patch-package
to modify node_modules/@nuxtjs/axios/lib/plugin.js
files
$cat patches/@nuxtjs+axios+5.13.6.patch
diff --git a/node_modules/@nuxtjs/axios/lib/module.js b/node_modules/@nuxtjs/axios/lib/module.js
index 36d41dd..e6f6b96 100755
--- a/node_modules/@nuxtjs/axios/lib/module.js
+++ b/node_modules/@nuxtjs/axios/lib/module.js
@@ -38,9 +38,9 @@ function axiosModule (_moduleOptions) {
}
// Transpile defu (IE11)
- if (nuxt.options.build.transpile /* nuxt 1 */) {
- nuxt.options.build.transpile.push(({ isClient }) => isClient && 'defu')
- }
+ // if (nuxt.options.build.transpile /* nuxt 1 */) {
+ // nuxt.options.build.transpile.push(({ isClient }) => isClient && 'defu')
+ // }
// Default prefix
const prefix = process.env.API_PREFIX || moduleOptions.prefix || '/'
diff --git a/node_modules/@nuxtjs/axios/lib/plugin.js b/node_modules/@nuxtjs/axios/lib/plugin.js
index fc4493e..b5388b7 100644
--- a/node_modules/@nuxtjs/axios/lib/plugin.js
+++ b/node_modules/@nuxtjs/axios/lib/plugin.js
@@ -193,9 +193,10 @@ export default (ctx, inject) => {
// runtimeConfig
const runtimeConfig = ctx.$config && ctx.$config.axios || {}
// baseURL
- const baseURL = process.browser
- ? (runtimeConfig.browserBaseURL || runtimeConfig.browserBaseUrl || runtimeConfig.baseURL || runtimeConfig.baseUrl || '<%= options.browserBaseURL || '' %>')
- : (runtimeConfig.baseURL || runtimeConfig.baseUrl || process.env._AXIOS_BASE_URL_ || '<%= options.baseURL || '' %>')
+ const baseURL = '<%= options.baseURL || '' %>'
+ // const baseURL = process.browser
+ // ? (runtimeConfig.browserBaseURL || runtimeConfig.browserBaseUrl || runtimeConfig.baseURL || runtimeConfig.baseUrl || '<%= options.browserBaseURL || '' %>')
+ // : (runtimeConfig.baseURL || runtimeConfig.baseUrl || process.env._AXIOS_BASE_URL_ || '<%= options.baseURL || '' %>')
// Create fresh objects for all default header scopes
// Axios creates only one which is shared across SSR requests!
Hmm the issue you are talking about should already be fixed by this PR nuxt/framework#516 but there haven't been any releases of the this module since June.
@pi0 is there are reason why changes haven't been released?
I think nuxt/framework#516 only fixes the problem with the baseURL.
I think there are at least three problems.
- serializer is not defined
- baseURL
- Expected pattern to be a non-empty string (in build)
The baseURL problem happens because process.browser and process.env are undefined in client. We can see this in console.log
Regarding the third, it happens in the following place at build time.
https://github.com/nuxt-community/axios-module/blob/main/lib/module.js#L41-L43
So nuxt/framework#516 will fix the baseURL problem and this issue itself will not be fixed.
Auth module depends on axios, so that package can't have nuxt 3 support until axios is fixed: https://github.com/nuxt-community/auth-module/issues/1520
I'm not familiar with what this plugin does, but for someone trying to get axios
working quickly with Nuxt 3, you can add a quick plugin, like:
plugins/axios.ts
import { defineNuxtPlugin } from '#app'
import axios from 'axios'
export default defineNuxtPlugin(() => {
return {
provide: {
axios: () => {
return axios.create({/* configuration here */})
}
}
}
})
And then you can access it like:
Usage example
<script setup lang="ts">
import { useNuxtApp } from '#app'
let { $axios } = useNuxtApp()
const axios = $axios()
axios.get('/req/path/123').then((response) => {
/* do things with response and response.data */
})
</script>
This works with both SSR and client-side as far as I can tell.
Here's a small module u can use to replicate this module while you guys wait for an update.
You need to install axios
, @nuxtjs/proxy
, consola
, and defu
as devDependencies or dependencies for it to work.
~~I got the proxy plugin working but you have to use it a bit differently, for it to work the same you need to set axios.proxy
as true
then add a proxy
object outside of the axios object with your proxy config (like you would when installing just the proxy module.)~~
Fixed.
nuxt.config.ts
import { defineNuxtConfig } from 'nuxt3'
// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
// no need to set @nuxtjs/proxy here
buildModules: [
'~/modules/nuxt-axios',
],
axios: {
credentials: true,
proxy: true // if you want to enable proxy
},
proxy: {
//proxy config
}
})
/modules/nuxt-axios/index.ts
import defu from 'defu'
import consola from 'consola'
import { resolve } from 'path'
import { defineNuxtModule, addPluginTemplate } from '@nuxt/kit'
const CONFIG_KEY = 'axios'
const logger = consola.withScope('nuxt:axios')
export default defineNuxtModule({
meta: {
name: 'nuxt-axios',
configKey: CONFIG_KEY,
compatibility: {
nuxt: '^3.0.0'
}
},
async setup(_moduleOptions, nuxt) {
// Combine options
const moduleOptions = {
...nuxt.options.axios,
..._moduleOptions,
...(nuxt.options.runtimeConfig && nuxt.options.runtimeConfig.axios)
}
// Default port
const defaultPort =
process.env.API_PORT ||
moduleOptions.port ||
process.env.PORT ||
process.env.npm_package_config_nuxt_port ||
(nuxt.options.server && nuxt.options.server.port) ||
3000
// Default host
let defaultHost =
process.env.API_HOST ||
moduleOptions.host ||
process.env.HOST ||
process.env.npm_package_config_nuxt_host ||
(nuxt.options.server && nuxt.options.server.host) ||
'localhost'
/* istanbul ignore if */
if (defaultHost === '0.0.0.0') {
defaultHost = 'localhost'
}
// Transpile defu (IE11)
if (nuxt.options.build.transpile && process.client/* nuxt 1 */) {
nuxt.options.build.transpile.push('defu')
}
// Default prefix
const prefix = process.env.API_PREFIX || moduleOptions.prefix || '/'
// HTTPS
const https = Boolean(nuxt.options.server && nuxt.options.server.https)
// Headers
const headers = {
common: {
Accept: 'application/json, text/plain, */*'
},
delete: {},
get: {},
head: {},
post: {},
put: {},
patch: {}
}
// Support baseUrl alternative
if (moduleOptions.baseUrl) {
moduleOptions.baseURL = moduleOptions.baseUrl
delete moduleOptions.baseUrl
}
if (moduleOptions.browserBaseUrl) {
moduleOptions.browserBaseURL = moduleOptions.browserBaseUrl
delete moduleOptions.browserBaseUrl
}
// Apply defaults
const options = defu(moduleOptions, {
baseURL: `http://${defaultHost}:${defaultPort}${prefix}`,
browserBaseURL: undefined,
credentials: false,
debug: false,
progress: true,
proxyHeaders: true,
proxyHeadersIgnore: [
'accept',
'cf-connecting-ip',
'cf-ray',
'content-length',
'content-md5',
'content-type',
'host',
'if-none-match',
'if-modified-since',
'x-forwarded-host',
'x-forwarded-port',
'x-forwarded-proto'
],
proxy: false,
retry: false,
https,
headers
})
// ENV overrides
/* istanbul ignore if */
if (process.env.API_URL) {
options.baseURL = process.env.API_URL
}
/* istanbul ignore if */
if (process.env.API_URL_BROWSER) {
options.browserBaseURL = process.env.API_URL_BROWSER
}
// Default browserBaseURL
if (typeof options.browserBaseURL === 'undefined') {
options.browserBaseURL = options.proxy ? prefix : options.baseURL
}
// Normalize options
if (options.retry === true) {
options.retry = {}
}
// Convert http:// to https:// if https option is on
if (options.https === true) {
const https = s => s.replace('http://', 'https://')
options.baseURL = https(options.baseURL)
options.browserBaseURL = https(options.browserBaseURL)
}
// globalName
options.globalName = nuxt.options.globalName || 'nuxt'
// Register plugin
addPluginTemplate({
src: resolve(__dirname, 'plugin.ts'),
filename: 'axios.options.mjs',
options
})
// Proxy integration
if (options.proxy) {
nuxt.options.proxy = typeof options.proxy === 'object' ? options.proxy : (typeof nuxt.options.proxy === 'object' ? nuxt.options.proxy : {})
nuxt['__module_container__'].requireModule('@nuxtjs/proxy')
}
// Set _AXIOS_BASE_URL_ for dynamic SSR baseURL
process.env._AXIOS_BASE_URL_ = options.baseURL
logger.debug(`baseURL: ${options.baseURL}`)
logger.debug(`browserBaseURL: ${options.browserBaseURL}`)
}
})
/modules/nuxt-axios/plugin.ts
import { defineNuxtPlugin } from '#app'
import Axios from 'axios'
import defu from 'defu'
'<% if (options.retry) { %>'
import axiosRetry from 'axios-retry'
'<% } %>'
// Axios.prototype cannot be modified
const axiosExtra = {
setBaseURL(baseURL) {
this.defaults.baseURL = baseURL
},
setHeader(name, value, scopes = 'common') {
for (const scope of Array.isArray(scopes) ? scopes : [scopes]) {
if (!value) {
delete this.defaults.headers[scope][name];
continue
}
this.defaults.headers[scope][name] = value
}
},
setToken(token, type, scopes = 'common') {
const value = !token ? null : (type ? type + ' ' : '') + token
this.setHeader('Authorization', value, scopes)
},
onRequest(fn) {
this.interceptors.request.use(config => fn(config) || config)
},
onResponse(fn) {
this.interceptors.response.use(response => fn(response) || response)
},
onRequestError(fn) {
this.interceptors.request.use(undefined, error => fn(error) || Promise.reject(error))
},
onResponseError(fn) {
this.interceptors.response.use(undefined, error => fn(error) || Promise.reject(error))
},
onError(fn) {
this.onRequestError(fn)
this.onResponseError(fn)
},
create(options) {
return createAxiosInstance(defu(options, this.defaults))
}
}
// Request helpers ($get, $post, ...)
for (const method of ['request', 'delete', 'get', 'head', 'options', 'post', 'put', 'patch']) {
axiosExtra['$' + method] = function () { return this[method].apply(this, arguments).then(res => res && res.data) }
}
const extendAxiosInstance = axios => {
for (const key in axiosExtra) {
axios[key] = axiosExtra[key].bind(axios)
}
}
const createAxiosInstance = axiosOptions => {
// Create new axios instance
const axios = Axios.create(axiosOptions)
axios.CancelToken = Axios.CancelToken
axios.isCancel = Axios.isCancel
axios.isAxiosError = Axios.isAxiosError
// Extend axios proto
extendAxiosInstance(axios)
// Intercept to apply default headers
axios.onRequest((config) => {
config.headers = { ...axios.defaults.headers.common, ...config.headers }
})
// Setup interceptors
'<% if (options.debug) { %>'; setupDebugInterceptor(axios); '<% } %>'
'<% if (options.credentials) { %>'; setupCredentialsInterceptor(axios); '<% } %>'
'<% if (options.progress) { %>'; setupProgress(axios); '<% } %>'
'<% if (options.retry) { %>'; axiosRetry(axios, JSON.parse('<%= JSON.stringify(options.retry) %>')); '<% } %>'
return axios
}
'<% if (options.debug) { %>'
const log = (level, ...messages) => console[level]('[Axios]', ...messages)
const setupDebugInterceptor = axios => {
// request
axios.onRequestError(error => {
log('error', 'Request error:', error)
})
// response
axios.onResponseError(error => {
log('error', 'Response error:', error)
})
axios.onResponse(res => {
log(
'info',
'[' + (res.status + ' ' + res.statusText) + ']',
'[' + res.config.method.toUpperCase() + ']',
res.config.url)
if (process.client) {
console.log(res)
} else {
console.log(JSON.stringify(res.data, undefined, 2))
}
return res
})
}
'<% } %>'
'<% if (options.credentials) { %>'
const setupCredentialsInterceptor = axios => {
// Send credentials only to relative and API Backend requests
axios.onRequest(config => {
if (config.withCredentials === undefined) {
if (!/^https?:\/\//i.test(config.url) || config.url.indexOf(config.baseURL) === 0) {
config.withCredentials = true
}
}
})
}
'<% } %>'
'<% if (options.progress) { %>'
const setupProgress = (axios) => {
if (process.server) {
return
}
// A noop loading inteterface for when $nuxt is not yet ready
const noopLoading = {
finish: () => { },
start: () => { },
fail: () => { },
set: () => { }
}
const $loading = () => {
const $nuxt = typeof window !== 'undefined' && window['$<%= options.globalName %>']
return ($nuxt && $nuxt.$loading && $nuxt.$loading.set) ? $nuxt.$loading : noopLoading
}
let currentRequests = 0
axios.onRequest(config => {
if (config && config.progress === false) {
return
}
currentRequests++
})
axios.onResponse(response => {
if (response && response.config && response.config.progress === false) {
return
}
currentRequests--
if (currentRequests <= 0) {
currentRequests = 0
$loading().finish()
}
})
axios.onError(error => {
if (error && error.config && error.config.progress === false) {
return
}
currentRequests--
if (Axios.isCancel(error)) {
if (currentRequests <= 0) {
currentRequests = 0
$loading().finish()
}
return
}
$loading().fail()
$loading().finish()
})
const onProgress = e => {
if (!currentRequests || !e.total) {
return
}
const progress = ((e.loaded * 100) / (e.total * currentRequests))
$loading().set(Math.min(100, progress))
}
axios.defaults.onUploadProgress = onProgress
axios.defaults.onDownloadProgress = onProgress
}
'<% } %>'
export default defineNuxtPlugin(ctx => {
// runtimeConfig
const runtimeConfig = ctx.$config && ctx.$config.axios || {}
// baseURL
const baseURL = process.client
? (runtimeConfig.browserBaseURL || runtimeConfig.browserBaseUrl || runtimeConfig.baseURL || runtimeConfig.baseUrl || '<%= options.browserBaseURL %>' || '')
: (runtimeConfig.baseURL || runtimeConfig.baseUrl || process.env._AXIOS_BASE_URL_ || '<%= options.baseURL %>' || '')
// Create fresh objects for all default header scopes
// Axios creates only one which is shared across SSR requests!
// https://github.com/mzabriskie/axios/blob/master/lib/defaults.js
const headers = JSON.parse('<%= JSON.stringify(options.headers) %>')
const axiosOptions = {
baseURL,
headers
}
'<% if (options.proxyHeaders) { %>'
// Proxy SSR request headers
if (process.server && ctx.ssrContext.req && ctx.ssrContext.req.headers) {
const reqHeaders = { ...ctx.ssrContext.req.headers }
for (const h of '<%= options.proxyHeadersIgnore %>'.split(',')) {
delete reqHeaders[h]
}
axiosOptions.headers.common = { ...reqHeaders, ...axiosOptions.headers.common }
}
'<% } %>'
if (process.server) {
// Don't accept brotli encoding because Node can't parse it
axiosOptions.headers.common['accept-encoding'] = 'gzip, deflate'
}
const axios = createAxiosInstance(axiosOptions)
ctx.vueApp.provide('axios', axios);
ctx.provide('axios', axios);
})
I can testify, @bcspragu's proposal works like a charm !
Either way, some other community modules such as the nuxt-community/auth-module are waiting for this update to start migrating to Nuxt 3 themselves. Would love to see @Teranode's fix tested, and hopefully included.
Sorry.
This hasn't been released yet π
In my case I am using
patch-package
to modifynode_modules/@nuxtjs/axios/lib/plugin.js
files
$cat patches/@nuxtjs+axios+5.13.6.patch
diff --git a/node_modules/@nuxtjs/axios/lib/module.js b/node_modules/@nuxtjs/axios/lib/module.js index 36d41dd..e6f6b96 100755 --- a/node_modules/@nuxtjs/axios/lib/module.js +++ b/node_modules/@nuxtjs/axios/lib/module.js @@ -38,9 +38,9 @@ function axiosModule (_moduleOptions) { } // Transpile defu (IE11) - if (nuxt.options.build.transpile /* nuxt 1 */) { - nuxt.options.build.transpile.push(({ isClient }) => isClient && 'defu') - } + // if (nuxt.options.build.transpile /* nuxt 1 */) { + // nuxt.options.build.transpile.push(({ isClient }) => isClient && 'defu') + // } // Default prefix const prefix = process.env.API_PREFIX || moduleOptions.prefix || '/' diff --git a/node_modules/@nuxtjs/axios/lib/plugin.js b/node_modules/@nuxtjs/axios/lib/plugin.js index fc4493e..b5388b7 100644 --- a/node_modules/@nuxtjs/axios/lib/plugin.js +++ b/node_modules/@nuxtjs/axios/lib/plugin.js @@ -193,9 +193,10 @@ export default (ctx, inject) => { // runtimeConfig const runtimeConfig = ctx.$config && ctx.$config.axios || {} // baseURL - const baseURL = process.browser - ? (runtimeConfig.browserBaseURL || runtimeConfig.browserBaseUrl || runtimeConfig.baseURL || runtimeConfig.baseUrl || '<%= options.browserBaseURL || '' %>') - : (runtimeConfig.baseURL || runtimeConfig.baseUrl || process.env._AXIOS_BASE_URL_ || '<%= options.baseURL || '' %>') + const baseURL = '<%= options.baseURL || '' %>' + // const baseURL = process.browser + // ? (runtimeConfig.browserBaseURL || runtimeConfig.browserBaseUrl || runtimeConfig.baseURL || runtimeConfig.baseUrl || '<%= options.browserBaseURL || '' %>') + // : (runtimeConfig.baseURL || runtimeConfig.baseUrl || process.env._AXIOS_BASE_URL_ || '<%= options.baseURL || '' %>') // Create fresh objects for all default header scopes // Axios creates only one which is shared across SSR requests!
its still not working
Any news on this? Maybe someone can review the @Teranode pull request.
@pi0 could you please assist (not sure who to tag)?
nuxt/auth is dependent on this, and it's quite a pain to rewrite that authentication package in nuxt 3.
@tntsoft You could try using these packages until they update theirs: https://github.com/Teranode/nuxt-module-alternatives
create plugins/axios.js and add this code inside
`import axios from 'axios'
export default () => { return { provide: { axios: axios.default } } } `
then you can use this.$axios
Seems like the upgrade is quite straightforward according to @Teranode, @bcspragu or @paleacci.
A first step could be to create a "next" branch that would allow axios-dependent projects to start migrating to Nuxt 3 ?
You don't really need that package anymore, ohmyfetch
is the recommended approach anyway: https://v3.nuxtjs.org/api/utils/$fetch#fetch