DEV Community

Alexander Kim
Alexander Kim

Posted on • Edited on

8 2

Using axios globally in a Vue 3 with provide/inject (composition API)

In a Vue 2 we had to use Vue.prototype in order to add global properties to a Vue instance. But in a Vue 3 we got "Composition API".

So, using a composition api, recommended way to add global properties, is by using provide/inject. Because config.globalProperties considered as an escape hatch

Let's get started.

1. Create a file called http.ts (you can name it as you wish):

import axios, { AxiosInstance } from 'axios'

const apiClient: AxiosInstance = axios.create({
  baseURL: 'https://api.openbrewerydb.org',
  headers: {
    'Content-type': 'application/json',
  },
})

export default apiClient
Enter fullscreen mode Exit fullscreen mode

It's our global Axios instance with the options.

2. Create a file symbols.ts

import { InjectionKey } from 'vue'
import { AxiosInstance } from 'axios'

export const AxiosKey: InjectionKey<AxiosInstance> = Symbol('http')
Enter fullscreen mode Exit fullscreen mode

This is required to type our Provide/Inject.

3. Go to main.ts

// libs
import http from '@/http'
import { AxiosKey } from '@/symbols'

const app = createApp(App)

app.provide(AxiosKey, http)
Enter fullscreen mode Exit fullscreen mode

We're providing our Axios instance globally here, using InjectionKey - AxiosKey, so it's typed now. Otherwise you would have to provide types every time you use inject()

4. Create a function to deal with undefined values, when you use inject():

import { inject, InjectionKey } from 'vue'

export function injectStrict<T>(key: InjectionKey<T>, fallback?: T) {
  const resolved = inject(key, fallback)
  if (!resolved) {
    throw new Error(`Could not resolve ${key.description}`)
  }
  return resolved
}
Enter fullscreen mode Exit fullscreen mode

It was found in this useful blog post

5. Using our global axios instance inside a component:

<script setup lang="ts">
import { ref, onMounted } from 'vue'

// typing inject
import { injectStrict } from '@/utils/injectTyped'
import { AxiosKey } from '@/symbols'

interface Breweries {
  id: string
  name: string
}

const http = injectStrict(AxiosKey) // it's typed now
const breweries = ref<Breweries[]>([])

onMounted(async () => {
  const resp = await http.get<Breweries[]>('/breweries')
  breweries.value = resp.data
})
</script>
Enter fullscreen mode Exit fullscreen mode

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (3)

Collapse
 
isimmons profile image
Ian Simmons

Great Demo. Thanks

Collapse
 
bobl profile image
Bob Lefevre

Excellent article that stopped me pulling my hair - thanks!

Collapse
 
pdmshrestha profile image
Padam Shrestha

What would be the best approach to use same axios instance on .js file with inject?

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay