How to fix Cannot use fetch in a non-async function in React

ReactBEGINNERMEDIUMUpdated Dec 9, 2025ยท 131 views

This error occurs when attempting to use the fetch API without properly declaring the containing function as async. In Next.js, fetch must be called with await inside an async function, particularly in Server Components.

Quick fix

Fixes Cannot use fetch in a non-async function

// Before - incorrect
export default function Page() {
  const data = fetch('https://api.example.com/data'); // Error!
  return <div>{/* ... */}</div>;
}

// After - correct
export default async function Page() {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  return <div>{/* ... */}</div>;
}
  1. Add async keyword to Server Component
  2. Convert Client Component to Server Component
  3. Use useEffect hook for Client Components
  4. Use SWR or React Query for Client Components
react โ€” error
// Before - incorrect
export default function Page() {
const data = fetch('https://api.example.com/data'); // Error!
return <div>{/* ... */}</div>;
}
// After - correct
export default async function Page() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return <div>{/* ... */}</div>;
}
Cannot use fetch in a non-async function

What this error means

This error appears when you try to use the `fetch()` API but haven't declared your function as `async`. The fetch API is promise-based and requires the use of `await` to handle the response, which means the containing function must be marked with the `async` keyword. In Next.js with the App Router, this commonly occurs when developers try to fetch data in components without properly using async/await syntax. Next.js Server Components support async functions, allowing you to fetch data directly in the component, but the component function must be declared as async. The error can also occur if you try to make a Client Component async, which is not supported in React. Client Components marked with `'use client'` cannot be async functions, and attempting to do so will trigger similar errors.

Typical symptoms

  • Error message stating "Cannot use fetch in a non-async function" or similar
  • Compilation or runtime errors when calling fetch without await
  • TypeError when trying to access fetch response data synchronously
  • Next.js build failures related to data fetching in components
  • Error "async/await is not yet supported in Client Components"

Common causes

  1. Calling fetch() without the await keyword in a regular (non-async) function
  2. Forgetting to add the async keyword to a component or function that uses fetch
  3. Attempting to make a Client Component (with "use client") an async function
  4. Using fetch in a Client Component without proper hooks like useEffect
  5. Mixing Server Component patterns with Client Component patterns incorrectly

How to fix "Cannot use fetch in a non-async function"

1Add async keyword to Server Component

If you're fetching data in a Server Component (default in Next.js App Router), simply add the async keyword to your component function:

typescript
// Before - incorrect
export default function Page() {
  const data = fetch('https://api.example.com/data'); // Error!
  return <div>{/* ... */}</div>;
}

// After - correct
export default async function Page() {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  return <div>{/* ... */}</div>;
}

Server Components can be async and support direct fetch calls with await.

2Convert Client Component to Server Component

If your component is marked with 'use client' but doesn't actually need client-side interactivity, remove the directive and make it an async Server Component:

typescript
// Remove this if not needed
// 'use client'

export default async function Page() {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  return <div>{data.title}</div>;
}

This is the recommended approach for data fetching in Next.js 13+.

3Use useEffect hook for Client Components

If you must fetch data in a Client Component, use the useEffect hook with state management:

typescript
'use client'

import { useState, useEffect } from 'react';

export default function ClientPage() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data');
        const result = await response.json();
        setData(result);
      } catch (err) {
        setError(err);
      } finally {
        setLoading(false);
      }
    }

    fetchData();
  }, []);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  return <div>{data?.title}</div>;
}

Note: Client-side fetching is generally not recommended when Server Components can be used.

4Use SWR or React Query for Client Components

For more robust client-side data fetching, use established libraries like SWR or React Query:

typescript
'use client'

import useSWR from 'swr';

const fetcher = (url: string) => fetch(url).then(res => res.json());

export default function ClientPage() {
  const { data, error, isLoading } = useSWR(
    'https://api.example.com/data',
    fetcher
  );

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error loading data</div>;
  return <div>{data.title}</div>;
}

These libraries provide caching, revalidation, and better error handling out of the box.

5Pass fetch promise from Server to Client Component

For advanced cases, fetch data in a Server Component and pass the promise to a Client Component using React's use hook:

typescript
// app/page.tsx (Server Component)
import ClientComponent from './ClientComponent';

export default function Page() {
  const dataPromise = fetch('https://api.example.com/data')
    .then(res => res.json());

  return <ClientComponent dataPromise={dataPromise} />;
}

// ClientComponent.tsx
'use client'

import { use } from 'react';

export default function ClientComponent({
  dataPromise
}: {
  dataPromise: Promise<any>
}) {
  const data = use(dataPromise);
  return <div>{data.title}</div>;
}

This pattern allows Server Components to initiate the fetch while Client Components handle the data.

Advanced notes

TypeScript Requirements: To use async Server Components with TypeScript, you need TypeScript 5.1.3 or higher and @types/react 18.2.8 or higher.

Caching Behavior: Next.js automatically caches fetch requests in Server Components by default. The data can be fetched at build time or request time and reused across requests. Use the cache and next.revalidate options to control this behavior:

typescript
const response = await fetch('https://api.example.com/data', {
  cache: 'force-cache', // or 'no-store'
  next: { revalidate: 3600 } // revalidate every hour
});

Route Handlers and Server Actions: You can also use async/await with fetch in Route Handlers (API routes) and Server Actions. These contexts always support async functions regardless of whether they're Server or Client Components.

Error Boundaries: When using async Server Components, wrap them in error boundaries to handle fetch failures gracefully. Create an error.tsx file in your route directory to catch and handle errors.

Streaming and Suspense: Server Components with async data fetching work seamlessly with React Suspense and Next.js streaming. Wrap async components in Suspense boundaries to show loading states while data is being fetched.

Frequently asked questions

What does "Cannot use fetch in a non-async function" mean?
This error appears when you try to use the fetch() API but haven't declared your function as async. The fetch API is promise-based and requires the use of await to handle the response, which means the containing function must be marked with the async keyword. js with the App Router, this commonly occurs when developers try to fetch data in components without properly using async/await syntax.
How do I fix "Cannot use fetch in a non-async function"?
This error occurs when attempting to use the fetch API without properly declaring the containing function as async. In Next.js, fetch must be called with await inside an async function, particularly in Server Components.
What causes "Cannot use fetch in a non-async function"?
Calling fetch() without the await keyword in a regular (non-async) function Forgetting to add the async keyword to a component or function that uses fetch Attempting to make a Client Component (with "use client") an async function
Is the "Cannot use fetch in a non-async function" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading