Tips for configuring the global API baseUrl for useFetch in Nuxt 3

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?

Answer №1

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 :-)

Answer №2

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.

Answer №3

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,
  ...
})

Answer №4

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)

Answer №5

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

Answer №6

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.

Answer №7

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:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enhancing Angular routing with multiple parameters

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 ...

The Extended Date type is indicating that the function cannot be located

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 ...

Utilizing inherited method in child component from parent component

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 ...

Setting up the API URL for a Nuxt.js project running on localhost at port 8080: What you need to know

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 ...

Strategies for capturing a module's thrown exception during loading process

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. ...

Achieve compatibility for two different types of route parameters in Vue.js

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 ...

Angular 2: A guide to connecting Input with model property using getter and setter functions

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 ...

Using Vue.js with SCSS or Sass

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 ...

Declaring Objects and Relationships in Angular Models

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 ...

What methods are available to me for creating a wrapper for an Angular Component that simply changes the component selector name?

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 ...

Mastering the art of calculating month differences on TypeScript dates in an Angular environment

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 ...

Why am I unable to apply the keyof operator from one type to another type, even though both types have identical keys defined but different value types?

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 ...

Exploring the implementation of a custom validator within an Angular service

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) { ...

Changing styles based on values within a v-for loop in Vue: Utilizing a computed property or alternative method

I am working with a component structured like this: Vue.component('mcp-item', { template: '#mcp-item-template', data() { return { name: "MCP v2", version: &q ...

How can I ensure my function waits for a promise to be resolved using Async / Await?

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 ...

Is it possible to import both type and value on the same line when isolatedModules=true?

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 ...

Deciphering TS2345: "The argument supplied, known as 'typeof MyComponent', cannot be assigned to the specified parameter type"

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 ...

Issue: the module '@raruto/leaflet-elevation' does not include the expected export 'control' as imported under the alias 'L' . This results in an error message indicating the absence of exports within the module

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/ ...

Creating custom TypeScript validation types at compile time

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 ...

Creating a Vue.js project using npm or yarn is proving to be a challenge for me

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. ...