Server Components fetch with async/await
To fetch data with the fetch API in Server Components, turn your component into an asynchronous function and await the fetch call. Make the component async and use await on the fetch promise, then await .json() on the response.
Identical fetch requests are memoized by default
Identical fetch requests in a React component tree are memoized by default. This allows you to fetch data in the component that needs it instead of drilling props down multiple levels.
Fetch requests are not cached by default
Fetch requests are not cached by default and will block the page from rendering until the request is complete. Use the 'use cache' directive to cache results, or wrap the fetching component in <Suspense> to stream fresh data at request time.
Server Components with ORM or database
Server Components are rendered on the server, so credentials and query logic will not be included in the client bundle. This allows you to safely make database queries using an ORM or database client. Always ensure requests are properly authenticated and authorized.
Server Action automatic invocation with forms
By convention, a Server Action is an async function used with startTransition. This happens automatically when the function is passed to a <form> using the action prop, or passed to a <button> using the formAction prop. When an action is invoked, Next.js can return both the updated UI and new data in a single server roundtrip.
Server Functions use POST method exclusively
Behind the scenes, Server Actions use the POST method, and only this HTTP method can invoke them. Server Functions are reachable via direct POST requests, not just through the application's UI.
Authentication and authorization required in Server Functions
Always verify authentication and authorization inside every Server Function, since Server Functions are reachable via direct POST requests. Refer to the Data Security guide for recommended patterns.
FormData automatic parameter in form-invoked Server Actions
When a Server Action is invoked in a form, the function automatically receives the FormData object. Extract the data using the native FormData methods, such as formData.get('fieldName').
Server Action invocation through event handlers
Server Functions can be invoked in Client Components by using event handlers such as onClick. The function call is asynchronous and returns a promise that can be awaited.
useActionState hook for pending state during Server Action
Use React's useActionState hook to show a loading indicator while executing a Server Action. The hook returns a state object, an action function, and a pending boolean that indicates whether the action is executing.
redirect() function behavior in Server Actions
Call redirect() within a Server Function to redirect the user to a different page after a mutation. Calling redirect() throws a framework-handled control-flow exception, and any code after it will not execute. If you need fresh data, call revalidatePath() or revalidateTag() beforehand.
Cookies API in Server Actions
Use the cookies API in a Server Action to get, set, and delete cookies using await cookies() to get the cookie store, then use methods like get('name')?.value, set('name', value), and delete('name'). When you set or delete a cookie in a Server Action, Next.js re-renders the current page and its layouts on the server so the UI reflects the new cookie value.
useEffect with Server Actions for automatic mutations
Use the React useEffect hook to invoke a Server Action when the component mounts or a dependency changes. Wrap the Server Action call with startTransition() to manage the pending state. This is useful for mutations that depend on global events or need to be triggered automatically.
Server Actions sequential dispatch limitation
Server Functions are designed for server-side mutations. The client currently dispatches and awaits them one at a time. This is an implementation detail and may change. If you need parallel data fetching, use data fetching in Server Components, or perform parallel work inside a single Server Function or Route Handler.
Cookie re-render behavior in Server Actions
When you set or delete a cookie in a Server Action, the server update applies to the current React tree, re-rendering, mounting, or unmounting components as needed. Client state is preserved for re-rendered components, and effects re-run if their dependencies changed.
useOffline experimental config for Server Actions
With the experimental useOffline config enabled, a Server Action interrupted by a connectivity drop stays pending and completes when the network returns.
Example: Form invoking Server Action for creating post
This example shows how to create a form that invokes a Server Action. The form passes FormData to the createPost Server Action, which receives it as the first parameter:
```tsx
import { createPost } from '@/app/actions'
export function Form() {
return (
<form action={createPost}>
<input type="text" name="title" />
<input type="text" name="content" />
<button type="submit">Create</button>
</form>
)
}
```
```ts
'use server'
import { auth } from '@/lib/auth'
export async function createPost(formData: FormData) {
const session = await auth()
if (!session?.user) {
throw new Error('Unauthorized')
}
const title = formData.get('title')
const content = formData.get('content')
// Mutate data
// Revalidate cache
}
```
Example: useActionState for pending feedback
This example shows how to use useActionState to display a loading indicator while a Server Action executes:
```tsx
'use client'
import { useActionState, startTransition } from 'react'
import { createPost } from '@/app/actions'
import { LoadingSpinner } from '@/app/ui/loading-spinner'
export function Button() {
const [state, action, pending] = useActionState(createPost, false)
return (
<button onClick={() => startTransition(action)}>
{pending ? <LoadingSpinner /> : 'Create Post'}
</button>
)
}
```
Example: Event handler invoking Server Action
This example shows how to invoke a Server Action from an onClick event handler in a Client Component:
```tsx
'use client'
import { incrementLike } from './actions'
import { useState } from 'react'
export default function LikeButton({ initialLikes }: { initialLikes: number }) {
const [likes, setLikes] = useState(initialLikes)
return (
<>
<p>Total Likes: {likes}</p>
<button
onClick={async () => {
const updatedLikes = await incrementLike()
setLikes(updatedLikes)
}}
>
Like
</button>
</>
)
}
```
Example: Redirect after mutation
This example shows how to redirect after a mutation, ensuring cached data is revalidated first:
```ts
'use server'
import { auth } from '@/lib/auth'
import { revalidatePath } from 'next/cache'
import { redirect } from 'next/navigation'
export async function createPost(formData: FormData) {
const session = await auth()
if (!session?.user) {
throw new Error('Unauthorized')
}
// Mutate data
// ...
revalidatePath('/posts')
redirect('/posts')
}
```
Example: Cookies in Server Action
This example shows how to get, set, and delete cookies in a Server Action:
```ts
'use server'
import { cookies } from 'next/headers'
export async function exampleAction() {
const cookieStore = await cookies()
// Get cookie
cookieStore.get('name')?.value
// Set cookie
cookieStore.set('name', 'Delba')
// Delete cookie
cookieStore.delete('name')
}
```
Example: useEffect with Server Action
This example shows how to use useEffect to invoke a Server Action when a component mounts:
```tsx
'use client'
import { incrementViews } from './actions'
import { useState, useEffect, useTransition } from 'react'
export default function ViewCount({ initialViews }: { initialViews: number }) {
const [views, setViews] = useState(initialViews)
const [isPending, startTransition] = useTransition()
useEffect(() => {
startTransition(async () => {
const updatedViews = await incrementViews()
setViews(updatedViews)
})
}, [])
// You can use `isPending` to give users feedback
return <p>Total Views: {views}</p>
}
```
Predictable values in components
Module imports, synchronous I/O, and pure computations produce the same result every time they run. Components using only these operations are prerendered automatically, and their output becomes part of the static HTML at build time.
Server Components provide initial data scoped to the segment that owns it
Server Components provide the initial data, scoped to the segment that owns it, as part of coordinating the data flow with data-fetching libraries and mutations.