---
title: "Overview"
description: "Nuxt data-fetching fundamentals and the core concepts and architecture of the Movk Nuxt API system."
canonical_url: "https://nuxt.mhaibaraai.cn/en/docs/api"
---
# Overview

> Nuxt data-fetching fundamentals and the core concepts and architecture of the Movk Nuxt API system.

## Nuxt Data Fetching Fundamentals

Nuxt provides three data-fetching approaches. Understanding the differences helps you choose the right Movk Nuxt wrapper.

- [`$fetch`](https://nuxt.com/docs/4.x/api/utils/dollarfetch): The low-level HTTP client, based on [ofetch](https://github.com/unjs/ofetch), usable on both server and client.```ts
// Called on user interaction — use $fetch
async function handleSubmit() {
  const result = await $fetch('/api/login', {
    method: 'POST',
    body: { username, password }
  })
}
```
- [`useFetch`](https://nuxt.com/docs/4.x/api/composables/use-fetch): A syntactic sugar wrapper around `useAsyncData` + `$fetch`.```ts
// Fetch data on page load — use useFetch
const { data: posts, status, error } = await useFetch('/api/posts')
```
- [`useAsyncData`](https://nuxt.com/docs/4.x/api/composables/use-async-data): The most flexible data-fetching composable.```ts
// Aggregate multiple endpoints — use useAsyncData
const { data } = await useAsyncData('dashboard', async () => {
  const [users, stats] = await Promise.all([
    $fetch('/api/users'),
    $fetch('/api/stats')
  ])
  return { users, stats }
})
```

## Key Parameters Explained

Three core parameters of `useFetch` (and `useApiFetch`) determine when and how requests are executed.

### `server`

Controls whether data fetching is executed on the server. **Defaults to true.**

**Behavior comparison:**

- `server: true` (default) — During SSR the request is made on the server; data is transferred to the client via payload and not re-fetched on the client.
- `server: false` — Executed on the client only. On first load, data starts fetching after hydration completes; `data` is initially `null`.

**Use cases:**

- `server: true` — SEO-relevant data, content required on first render.
- `server: false` — Non-SEO-sensitive data (user comments, personalized recommendations, analytics), reducing server load.

```ts
// Article list needs SEO — server: true (default)
const { data: posts } = await useApiFetch<Post[]>('/posts')

// Comment data doesn't need SSR — server: false
const { data: comments } = useApiFetch('/comments', {
  server: false,
  lazy: true,
})
```

> [!NOTE]
> 
> server: false
> 
>  is typically paired with 
> 
> lazy: true
> 
> , which is exactly the preset behavior of 
> 
> useClientApiFetch
> 
> .

### `lazy`

Controls whether client-side navigation is blocked. **Defaults to false.**

**Behavior comparison:**

- `lazy: false` (default) — Blocks navigation via Vue Suspense, waiting for data before completing the route transition. The user never sees a loading state.
- `lazy: true` — Does not block navigation; the page displays immediately while data loads in the background. You must handle the loading state manually.

**Use cases:**

- `lazy: false` — Core page data without which the page cannot render correctly.
- `lazy: true` — Secondary data, non-above-the-fold data, scenarios where a skeleton screen can be shown first.

```ts
// Core data — block navigation and wait for data (default)
const { data: article } = await useApiFetch<Article>(`/articles/${id}`)

// Secondary data — don't block navigation, load in background
const { data: related, status } = useLazyApiFetch<Article[]>(
  `/articles/${id}/related`
)
```

```vue
<template>
  <!-- Handle loading state when using lazy -->
  <div v-if="status === 'pending'">
    <USkeleton class="h-20 w-full" />
  </div>
  <RelatedArticles v-else :articles="related" />
</template>
```

> [!NOTE]
> 
> During SSR, 
> 
> lazy
> 
>  behaves nearly the same as non-lazy (both wait for data); the difference primarily applies during 
> 
> client-side navigation
> 
> .

### `immediate`

Controls whether the request fires immediately when the composable is initialized. **Defaults to true.**

**Behavior comparison:**

- `immediate: true` (default) — Triggers the request on creation.
- `immediate: false` — No automatic request; `status` is `idle`. You must call `execute()` manually.

**Use cases:**

- `immediate: true` — Data needed as soon as the page loads.
- `immediate: false` — Requests that should only be triggered after a user action.

```ts
// Pre-define a form-submit request, don't auto-execute
const { data, execute, status, error } = useApiFetch('/login', {
  method: 'POST',
  body: credentials,
  immediate: false,
  lazy: true,
})

// Trigger manually when the user clicks the login button
async function handleLogin() {
  await execute()
  if (!error.value) {
    navigateTo('/dashboard')
  }
}
```

> [!TIP]
> 
> immediate: false
> 
>  is commonly paired with 
> 
> lazy: true
> 
> . If only 
> 
> immediate: false
> 
>  is set without 
> 
> lazy: true
> 
> , Suspense will still wait (even though the request never fires), which may cause the page to hang.

## Movk Nuxt API System

Movk Nuxt provides an API client factory based on `$fetch.create()` (the [`$api` plugin](https://nuxt.mhaibaraai.cn/docs/api/api-plugin)) and a set of composables that wrap `useFetch`, adding unified auth, business code checking, Toast notifications and other enhancements on top of Nuxt's native data-fetching capabilities.

```text
nuxt.config.ts (movk.api config)
    |
    v
api.factory.ts plugin — creates $api instance
    |
    v
Interceptor chain
├── onRequest:       Auth injection -> debug logging -> movk:api:request hook
├── onResponse:      Business check -> data unwrap -> movk:api:response hook -> Toast
└── onResponseError: 401 handling -> movk:api:error hook -> Toast
    |
    v
Composables
├── useApiFetch           useFetch + $api (SSR/CSR universal)
├── useLazyApiFetch       lazy: true preset
├── useClientApiFetch     server: false, lazy: true preset
├── useUploadWithProgress XHR upload + progress
├── useDownloadWithProgress fetch + ReadableStream download + progress
└── useApiStream          $api.stream() + SSE parsing + abort
```

Streaming responses (`text/event-stream`) never enter the business-check and unwrapping chain: as soon as
`onResponse` detects a readable stream it short-circuits, handing over to
[`useApiStream`](https://nuxt.mhaibaraai.cn/en/docs/composables/use-api-stream) or [`createChatTransport`](https://nuxt.mhaibaraai.cn/en/docs/api/chat-transport).

### Multi-Endpoint Support

Multiple API endpoints can be configured, each with its own baseURL, auth, Toast and response rules. Switch endpoints with the `endpoint` option or `$api.use()`.

> [!TIP]
> See: /docs/getting-started/configuration#endpoints
> 
> Learn about endpoint configuration options

### Automatic Authentication

Integrates with `nuxt-auth-utils`. When enabled, each request automatically extracts the token from the session and injects it into the request headers. Supports nested paths (e.g. `user.accessToken`) and multiple token formats (Bearer, Basic, Custom).

> [!TIP]
> See: /docs/getting-started/configuration#auth
> 
> Learn about authentication configuration options

### Business Status Code Check

The `$api` interceptor automatically checks whether the response `code` is in `successCodes`, throwing an `ApiError` and showing a Toast on business failure.

> [!TIP]
> See: /docs/api/api-plugin#data-unwrapping-and-business-validation
> 
> See interactive examples for business validation and 
> 
> skipBusinessCheck

### Data Unwrapping

The `$api` interceptor automatically extracts the `dataKey` field (default `data`) from the response; the generic `T` directly maps to the business data type.

> [!TIP]
> See: /docs/api/api-plugin#data-unwrapping-and-business-validation
> 
> See interactive examples for unwrapping and 
> 
> skipUnwrap

### Toast Notifications

Success/failure Toasts are shown automatically. Supports four levels of configuration priority: request-level > endpoint-level > global-level > built-in defaults. Can be disabled or customized at any level.

> [!TIP]
> See: /docs/getting-started/configuration#toast
> 
> Learn about Toast configuration options

### 401 Unauthorized Handling

When an HTTP 401 is received, the default behavior clears the session and redirects to the login page. This can be intercepted via [API Hooks](https://nuxt.mhaibaraai.cn/docs/api/hooks#movkapiunauthorized) to implement custom logic (e.g. token refresh).

> [!TIP]
> See: /docs/getting-started/configuration#auth
> 
> Learn about 401 handling configuration options


## Sitemap

See the full [sitemap](https://nuxt.mhaibaraai.cn/sitemap.md) for all pages.
