Is there a way to globally set the baseUrl used in the useFetch composable, possibly through nuxt.config.ts?
How can I prevent having to specify it in each individual useFetch call?
Is there a way to globally set the baseUrl used in the useFetch composable, possibly through nuxt.config.ts?
How can I prevent having to specify it in each individual useFetch call?
To set the baseURL
in your nuxt.config.js|ts
, you can follow this example:
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
// ...
runtimeConfig: {
public: {
baseURL: process.env.BASE_URL || 'https://api.example.com/',
},
},
// ...
(Alternatively, you can use a fixed value or solely rely on the environment variable)
In addition, include this composable:
// /composables/useMyFetch.js
export const useMyFetch = (request, opts) => {
const config = useRuntimeConfig()
return useFetch(request, { baseURL: config.public.baseURL, ...opts })
}
If you prefer type safety, consider implementing it like so:
// /composables/useMyFetch.ts
export const useMyFetch: typeof useFetch = (request, opts?) => {
const config = useRuntimeConfig()
return useFetch(request, { baseURL: config.public.baseURL, ...opts })
}
This will allow you to utilize useMyFetch
instead of useFetch
with the specified baseURL configuration :-)
A potential solution could involve utilizing the following composable
/composables/useJsonP.ts
export const useJsonP = async (path) => {
return await useFetch(() => `https://jsonplaceholder.typicode.com/${path}`)
}
This can be implemented in your view like so:
<script setup>
const jsonP = await useJsonP('todos/1')
</script>
<template>
<div>
<pre>{{ jsonP.data }}</pre>
</div>
</template>
By taking this approach, there is no need to manually define and configure the functionality elsewhere. This provides a straightforward method for creating reusable code snippets that can be easily imported into your components/views using Nuxt's DX capabilities.
If you're aiming to implement this functionality in Typescript, consider inferring the parameters from useFetch
to avoid making changes to your code if there are adjustments within Nuxt.
Customize your base URL based on your environment settings
As mentioned by others, start by setting your base URL in the public section of your runtime configuration:
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
// ...
runtimeConfig: {
public: {
baseURL: process.env.BASE_URL || 'https://api.example.com/',
},
},
// ...
Encapsulate useFetch within a custom composable
The definition of useFetch
involves various type variables and overloads, with valid options for the argument changing depending on the types of requests/results passed to it. This complexity makes accurate re-typing challenging.
In addition, even if we manage to re-type it accurately, any modifications to the definition will render our wrapper ineffective. Fortunately, there's a straightforward solution. Adopt the type of useFetch
and apply it again:
// composables/useAPIFetch.ts
import { useFetch } from "#app"
type useFetchType = typeof useFetch
// adapt useFetch with necessary configurations to communicate with our API
export const useAPIFetch: useFetchType = (path, options = {}) => {
const config = useRuntimeConfig()
// adjust options as required
options.baseURL = config.public.baseUrl
return useFetch(path, options)
}
It's crucial not to redefine any type variables, parameter argument types, or return types explicitly since we're borrowing all of them from the type of useFetch
.
Integrate your new composable
Implement it in your page / component to ensure proper handling of types:
// components/Foo.vue
const { data, error, pending } = await useAPIFetch<ResultsType>("/my-path", {
method: "POST",
body: data,
...
})
You can incorporate the use of .env in the following manner:
within your .env file:
NUXT_PUBLIC_BASE_URL = https://www.anotherapi.com
inside your nuxt.config.js/ts file:
runtimeConfig: {
public: {
BASE_URL: 'some default value',
},
},
as specified in the documentation, BASE_URL
will automatically be replaced by NUXT_PUBLIC_BASE_URL
(no need to utilize process.env.NUXT_PUBLIC_BASE_URL
)
and within a composable, you can implement:
const configuration = useRuntimeConfig();
console.log('the base URL is', configuration.baseUrl)
One way to optimize code is by creating a $fetch instance that can be reused when creating a new composable. Here's an example of how to create a $fetch instance:
// Set up a fetch object with a predefined baseURL
const apiFetch = $fetch.create({ baseURL: '/api' })
// Use it just like $fetch
const {data, pending, errors, refresh} = await apiFetch('/test') // This is equivalent to $fetch('/test', { baseURL: '/api' })
For more information, visit: https://github.com/nuxt/nuxt/discussions/15930
To implement custom fetching in your Nuxt application, you need to make some configurations.
runtimeConfig: {
public: {
baseURL: process.env.BASE_URL || 'https://yourBaseURL.com/',
},
}
In the `composables` directory, create a new file and add the following code:
export const useCustomFetch = (request , opts) =>{
const config = useRuntimeConfig()
return useFetch(request,{
baseURL:config.public.baseURL,
onRequest({ request, options }) {
// Set the request headers
},
onRequestError({ request, options, error }) {
// Handle the request errors
},
onResponse({ request, response, options }) {
// Process the response data
return response._data
},
onResponseError({ request, response, options }) {
// Handle the response errors
},
...opts})
}
You can now utilize this composable wrapper in your components. This composable also includes an interceptor feature for additional functionality.
If you're still on the hunt for a solution to the initial inquiry, one approach is to utilize runtimeConfig and environment variables in your nuxt.config
file. Of course, you also have the option to substitute the environment variables with hardcoded values if that's more your style.
Within your nuxt.config.js/ts
:
runtimeConfig: {
SOME_SECRET_KEY: process.env.SOME_SECRET_KEY,
public: {
SOME_API_KEY: process.env.SOME_API_KEY,
},
},
Then, in someComposable.js
:
const config = useRuntimeConfig();
You can then access your variables as demonstrated by config.public.SOME_API_KEY
.
Hoping this explanation proves useful. For additional details, refer to:
When I am using either routerLink or router.navigate, I face an issue where I have an array containing multiple values that need to be serialized into ?id=val1&id=val2. However, the problem arises when trying to set an optional route parameter as an ar ...
I came across this helpful gist with date extensions: https://gist.github.com/weslleih/b6e7628416a052963349494747aed659 However, when attempting to use the functions, I encountered a runtime error stating: TypeError: x.isToday is not a function I foun ...
In the structure of my application, the root component is mounted inside main.js (generated with vue-cli): <template @parallax-event="parallaxHandler" > <div id="app"> <RepeatingWords></RepeatingWords> <NavigationBar>&l ...
Within my vue file, I have specified that the base URL for my REST API is http://localhost:8080/api/. When accessing http://localhost:8080/api/dfc/system/docbases directly, the response returned is as follows: ["gr_swy","SubWayX_DEMO"] However, I am atte ...
Is there a way to validate environment variables and display an error message on the page if the environment is found to be invalid? The config.ts file will throw an exception if the env variable is invalid. import * as yup from 'yup' console. ...
I am trying to set up nested sets of categories in URLs that lead to specific products, but I'm having trouble with matching the routes correctly. Here are the URLs I want: --- renders a "category.show.vue": /$categorySlug+ app.com/catA/cat ...
I'm currently developing an Angular 2 web application. The model I have created consists of a few primary properties, along with other properties that are calculated based on those primary values. For each property in my model, I have implemented get ...
I find it more appealing to separate style from my HTML, so having CSS inside the same file as my code bothers me. Instead of using <style> tags with CSS mixed into my components, I prefer to use Sass or SCSS files. I usually have a single file for ...
Wondering if it's possible to declare an object inside my model. First attempt: export class Employee{ emp_id: number; emp_fname: string; emp_lname: string; emp_birth: string; emp_status: string; emp_photo: string; emp_dep ...
Having experience with React, you can simplify a library component in your app by giving it a new name like this: const MyAppTable = (props) => <LibraryTable ...props />; I'm interested in achieving a similar result in Angular, but I'm ...
Currently, I am working with Angular 7. Suppose I have a fixed rate X, for example, an amount I need to pay each month. Now, if I have two specified dates startDate and endDate, I want to calculate the total payment due for this given time period. To prov ...
Consider this code snippet. I am encountering a TypeScript error specifically on the last compat[k] line with the following error message: Type 'keyof T' cannot be used to index type 'Partial<CompatType>' export type KeysOfType ...
I have been attempting to implement a custom validator to validate if an email is already in use. After consulting the documentation and reading various articles, I have come up with the following code: In my auth.service.ts file checkEmail(email) { ...
I am working with a component structured like this: Vue.component('mcp-item', { template: '#mcp-item-template', data() { return { name: "MCP v2", version: &q ...
I'm running into an issue where I want my function to keep executing until the nextPageToken is null. The problem occurs when the function runs for the first time, it waits for the promise to resolve. However, if there is a nextPageToken present in th ...
Did you know with Typescript, you can do type-only imports? import type { Foo } from "./types" If the file exports both types and values, you can use two separate import statements like this: import type { Foo } from "./types"; import ...
I am facing an issue while attempting to integrate a Typescript React component with react-onclickoutside. The error message that I encounter is as follows: TS2345: Argument of type 'typeof MyComponent' is not assignable to parameter of type &apo ...
Looking for guidance on adding a custom Leaflet package to my Angular application called "leaflet-elevation". The package can be found at: https://github.com/Raruto/leaflet-elevation I have attempted to integrate it by running the command: npm i @raruto/ ...
Is it possible to create custom type definitions in TypeScript that are only checked during compile time? I want users to define a value for a variable (that won't change at runtime) and validate if it meets certain criteria. For example, requiring a ...
I'm currently facing some challenges when trying to create a Vue.js project using npm or yarn. Here is the command I am using: $ vue init webpack my-project # Installing project dependencies ... # ======================== events. ...