Try   HackMD

Nuxt3 API Proxy Setup

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

To start a new application, in order NOT to encounter CORS issue in dev mode, it's always crucial to handle api proxy setup if you need another third party backend service as source.

Here is a quick guideline for beginners to setup.

Flow

There are two possible flows.

I. Nuxt page

User enters a page and fetch api related with third party server in either CSR or SSR.

Nuxt Page Fetch api through useFetch or $fetch directly Nitro Server API Proxy Route > Backend service

II. Server route

User enters a server only route and the route requires some API response from third party server.

Server Route Fetch api through $fetch directly > Nitro Server API Proxy Route > Backend service

Background

Here are simples example for developers to understand the condition of backend service and api entrypoint.

API Base Url

The domain of backend service, it'll change by environment.

.env

NUXT_PUBLIC_API_BASE_URL=http://localhost:3005

.env.production

NUXT_PUBLIC_API_BASE_URL=https://ec-bot-web.line-apps-beta.com

This variable will be referred as useRuntimeConfig().public.apiBaseUrl in whole nuxt project.

API Entrypoint

The api endpoint to serve response. Imagine that calling http://localhost:3005/hello or https://ec-bot-web.line-apps-beta.com/hello
will response a simple JSON.

{api-base-url}/hello

{
  "hello": "world"
}

Get Started

To fetch api, no matter it comes from nuxt page or server route, the path will be like /api/** so it can be defined as api proxy route pattern later.

Nuxt Page

Here are two simple examples to fetch api from nuxt pages.

I. Fetch api through useFetch composable.

// pages/hello-world.vue
const { data } = await useFetch('/api/hello')

II. Fetch api through useAsyncData ($fetch) composable.

// pages/hello-world.vue
const { data } = await useAsyncData('hello', () => $fetch('/api/hello'))

Server Route

Here is an example to fetch backend service api in server route. User will get hello world string by typing URL {your-nitro-host}/hello-world.

// server/routes/hello-world
export default defineEventHandler(async (event) => {
  const { hello } = await $fetch('/api/hello')
  return `hello ${hello}`
})

Nitro Server

Add a proxy api endpoint in nitro server to handle CORS issue. It will replace /api/** with /** and add proxyUrl at the beginning. For example: /api/hello will be transformed to http://localhost:3005/hello and proxy the request.

// server/api/[...].ts
import { joinURL } from 'ufo'

export default defineEventHandler(async (event) => {
  const proxyUrl = useRuntimeConfig().public.apiBaseUrl
  const path = event.path.replace(/^\/api\//, '')
  const target = joinURL(proxyUrl, path)

  return proxyRequest(event, target)
})

That's it! Now you can feel free to request third party backend service api in your application.

Summary

It's recommend to use proxyRequest instead of devServer if you need to proxy request in both client and server side because devServer will NOT proxy request in nitro server itself. Which means request from nitro server to nitro server won't trigger a proxy that case. Besides, the api flow will be precise and easy to trace from either CSR or SSR.

tags: Work Nuxt3 Nitro Server proxyRequest