### Install Dependencies and Start Dev Server
Source: https://github.com/vercel/swr-site/blob/main/README.md
Use these commands to install project dependencies with pnpm and start the local development server. Visit localhost:3000 to preview changes.
```bash
pnpm install
pnpm dev
```
--------------------------------
### Basic useSWRMutation Setup
Source: https://github.com/vercel/swr-site/blob/main/content/docs/mutation.es.mdx
Demonstrates the basic setup for useSWRMutation, including defining a fetcher function and triggering the mutation. The fetcher receives the URL and an argument object.
```tsx
import useSWRMutation from 'swr/mutation'
// Fetcher implementation.
// The extra argument will be passed via the `arg` property of the 2nd parameter.
// In the example below, `arg` will be `'my_token'`
async function updateUser(url, { arg }: { arg: string }) {
await fetch(url, {
method: 'POST',
headers: {
Authorization: `Bearer ${arg}`
}
})
}
function Profile() {
// A useSWR + mutate like API, but it will not start the request automatically.
const { trigger } = useSWRMutation('/api/user', updateUser, options)
return
}
```
--------------------------------
### Install SWR
Source: https://github.com/vercel/swr-site/blob/main/content/docs/getting-started.mdx
Run this command in your React project directory to install SWR.
```bash
npm i swr
```
--------------------------------
### Example 1: Index Based Paginated API
Source: https://github.com/vercel/swr-site/blob/main/content/docs/pagination.mdx
Demonstrates how to use useSWRInfinite with an index-based pagination API. The `getKey` function generates request keys based on the page index.
```APIDOC
## Example 1: Index Based Paginated API
### Description
This example shows how to fetch data from an index-based paginated API using `useSWRInfinite`.
### Request Example (API)
```plaintext
GET /users?page=0&limit=10
[
{ name: 'Alice', ... },
{ name: 'Bob', ... },
{ name: 'Cathy', ... },
...
]
```
### Code Example (React)
```jsx
import useSWRInfinite from 'swr/infinite'
// A function to get the SWR key of each page,
// its return value will be accepted by `fetcher`.
// If `null` is returned, the request of that page won't start.
const getKey = (pageIndex, previousPageData) => {
if (previousPageData && !previousPageData.length) return null // reached the end
return `/users?page=${pageIndex}&limit=10` // SWR key
}
function App () {
const { data, size, setSize } = useSWRInfinite(getKey, fetcher)
if (!data) return 'loading'
// We can now calculate the number of all users
let totalUsers = 0
for (let i = 0; i < data.length; i++) {
totalUsers += data[i].length
}
return
{totalUsers} users listed
{data.map((users, index) => {
// `data` is an array of each page's API response.
return users.map(user =>
{user.name}
)
})}
}
```
### Notes
- The `getKey` function is crucial for `useSWRInfinite` and determines the request key for each page based on the page index and previous page data.
- The `data` returned by `useSWRInfinite` is an array of arrays, where each inner array represents the data for a single page.
```
--------------------------------
### Integrate SWR with Next.js App and Pages Router
Source: https://context7.com/vercel/swr-site/llms.txt
Examples demonstrating server-side prefetching in App Router layouts, client-side consumption, and Pages Router static generation with fallback data.
```jsx
// app/layout.tsx - Server Component with prefetching
import { SWRConfig } from 'swr'
async function fetchUser() {
const res = await fetch('https://api.example.com/user')
return res.json()
}
export default async function RootLayout({ children }) {
// Initiate fetching on server
const userPromise = fetchUser()
return (
{children}
)
}
// app/page.tsx - Client Component
'use client'
import useSWR from 'swr'
const fetcher = url => fetch(url).then(res => res.json())
export default function Page() {
// Data is pre-filled from server, then kept fresh on client
const { data: user } = useSWR('/api/user', fetcher)
return
Hello, {user?.name}
}
// pages/posts.js - Pages Router with getStaticProps
import useSWR, { SWRConfig, unstable_serialize } from 'swr'
export async function getStaticProps() {
const posts = await fetchPosts()
return {
props: {
fallback: {
'/api/posts': posts,
// For array keys, use unstable_serialize
[unstable_serialize(['posts', 'featured'])]: await fetchFeaturedPosts()
}
},
revalidate: 60
}
}
export default function PostsPage({ fallback }) {
return (
)
}
function PostList() {
// Pre-rendered data available immediately
const { data } = useSWR('/api/posts', fetcher)
return data?.map(post => {post.title})
}
```
--------------------------------
### Example 2: Cursor or Offset Based Paginated API
Source: https://github.com/vercel/swr-site/blob/main/content/docs/pagination.mdx
Illustrates using useSWRInfinite with a cursor-based pagination API. The `getKey` function dynamically includes the cursor from the previous page's response.
```APIDOC
## Example 2: Cursor or Offset Based Paginated API
### Description
This example demonstrates how to use `useSWRInfinite` with a cursor-based or offset-based paginated API, where the next page's request depends on a cursor provided in the previous response.
### Request Example (API)
```plaintext
GET /users?cursor=123&limit=10
{
data: [
{ name: 'Alice' },
{ name: 'Bob' },
{ name: 'Cathy' },
...
],
nextCursor: 456
}
```
### Code Example (React)
```jsx
import useSWRInfinite from 'swr/infinite'
const getKey = (pageIndex, previousPageData) => {
// reached the end
if (previousPageData && !previousPageData.data) return null
// first page, we don't have `previousPageData`
if (pageIndex === 0) return `/users?limit=10`
// add the cursor to the API endpoint
return `/users?cursor=${previousPageData.nextCursor}&limit=10`
}
// ... rest of the component using useSWRInfinite with this getKey function
```
### Notes
- The `getKey` function is adapted to use the `nextCursor` from the `previousPageData` to construct the URL for the subsequent page.
- This approach allows `useSWRInfinite` to handle various pagination strategies effectively.
```
--------------------------------
### Configure SWR with LocalStorage Cache Provider
Source: https://github.com/vercel/swr-site/blob/main/content/docs/advanced/cache.es.mdx
Example of integrating the localStorageProvider into SWRConfig to enable persistent caching across page reloads or application restarts.
```jsx
```
--------------------------------
### Data Fetching with SWR useUser Hook
Source: https://github.com/vercel/swr-site/blob/main/content/docs/getting-started.mdx
This refactored example uses a `useUser` hook with SWR to fetch data directly within the components that need it. This simplifies prop drilling and improves maintainability.
```jsx
// page component
function Page ({ userId }) {
return
}
function Content ({ userId }) {
const { user, isLoading } = useUser(userId)
if (isLoading) return
return
Welcome back, {user.name}
}
function Avatar ({ userId }) {
const { user, isLoading } = useUser(userId)
if (isLoading) return
return
}
```
--------------------------------
### Subscribe Function Example
Source: https://github.com/vercel/swr-site/blob/main/content/docs/subscription.mdx
An example of a subscribe function that uses a remote service to subscribe to data and returns a cleanup function.
```typescript
function subscribe(key, { next }) {
const sub = remote.subscribe(key, (err, data) => next(err, data))
return () => sub.close()
}
```
--------------------------------
### Cursor Based Paginated API Key Generation
Source: https://github.com/vercel/swr-site/blob/main/content/docs/pagination.mdx
Example of a `getKey` function for a cursor-based paginated API. It uses the `nextCursor` from the previous page's data to fetch the subsequent page.
```jsx
const getKey = (pageIndex, previousPageData) => {
// reached the end
if (previousPageData && !previousPageData.data) return null
// first page, we don't have `previousPageData`
if (pageIndex === 0) return `/users?limit=10`
// add the cursor to the API endpoint
return `/users?cursor=${previousPageData.nextCursor}&limit=10`
}
```
--------------------------------
### Index Based Paginated API Key Generation
Source: https://github.com/vercel/swr-site/blob/main/content/docs/pagination.mdx
Example of a `getKey` function for an index-based paginated API. It constructs the request URL based on the page index and stops when the previous page returns no data.
```jsx
// A function to get the SWR key of each page,
// its return value will be accepted by `fetcher`.
// If `null` is returned, the request of that page won't start.
const getKey = (pageIndex, previousPageData) => {
if (previousPageData && !previousPageData.length) return null // reached the end
return `/users?page=${pageIndex}&limit=10` // SWR key
}
```
--------------------------------
### Use SWR Hooks in Client Components
Source: https://github.com/vercel/swr-site/blob/main/content/docs/with-nextjs.es.mdx
To use SWR's client-side data fetching hooks, mark your component with the 'use client' directive or import SWR within a client component. This example shows basic usage with a fetcher function.
```tsx
'use client'
import useSWR from 'swr'
export default function Page() {
const { data } = useSWR('/api/user', fetcher)
return
{data.name}
}
```
--------------------------------
### Mutate Multiple Cache Items by Key Prefix
Source: https://github.com/vercel/swr-site/blob/main/content/docs/mutation.mdx
Use a filter function with the global `mutate` API to revalidate specific cache keys. This example revalidates all keys starting with '/api/item?id='.
```jsx
import { mutate } from 'swr'
// Or from the hook if you customized the cache provider:
// { mutate } = useSWRConfig()
mutate(
key => typeof key === 'string' && key.startsWith('/api/item?id='),
undefined,
{ revalidate: true }
)
```
--------------------------------
### Mutate Multiple Keys with Filter Function
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v2.mdx
Demonstrates how to use the global `mutate` function with a filter to revalidate or clear specific cached keys. This example clears all keys starting with '/api/item?id='.
```jsx
import { mutate } from 'swr'
// Or from the hook if you have customized your cache provider:
// { mutate } = useSWRConfig()
// Mutate single resource
mutate(key)
// Mutate multiple resources and clear the cache (set to undefined)
mutate(
key => typeof key === 'string' && key.startsWith('/api/item?id=') ,
undefined,
{ revalidate: false }
)
```
--------------------------------
### Import and Basic Usage of useSWRInfinite
Source: https://github.com/vercel/swr-site/blob/main/content/docs/pagination.mdx
Demonstrates how to import and use the useSWRInfinite hook. It returns data, error, loading states, and functions to manage page size.
```jsx
import useSWRInfinite from 'swr/infinite'
// ...
const { data, error, isLoading, isValidating, mutate, size, setSize } = useSWRInfinite(
getKey, fetcher?, options?
)
```
--------------------------------
### Import SWR Hooks
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v1.es.mdx
Import the main SWR hook and the infinite hook. If `useSWRInfinite` is not used, it won't be included in the bundle.
```javascript
import useSWR from 'swr'
import useSWRInfinite from 'swr/infinite'
```
--------------------------------
### Pass arguments to fetcher
Source: https://github.com/vercel/swr-site/blob/main/content/docs/arguments.mdx
Demonstrates equivalent ways to pass the key to the fetcher function.
```js
useSWR('/api/user', () => fetcher('/api/user'))
useSWR('/api/user', url => fetcher(url))
useSWR('/api/user', fetcher)
```
--------------------------------
### Subscribe Function with Updater
Source: https://github.com/vercel/swr-site/blob/main/content/docs/subscription.mdx
An example of a subscribe function where the `next` callback receives an updater function to modify the previous data.
```typescript
function subscribe(key, { next }) {
const sub = remote.subscribe(key, (err, data) => next(err, prev => prev.concat(data)))
return () => sub.close()
}
```
--------------------------------
### Subscribe to WebSocket Data
Source: https://github.com/vercel/swr-site/blob/main/content/docs/subscription.mdx
Example of using `useSWRSubscription` to subscribe to messages from a WebSocket server. Handles loading, error, and data states.
```tsx
import useSWRSubscription from 'swr/subscription'
function App() {
const { data, error } = useSWRSubscription('ws://...', (key, { next }) => {
const socket = new WebSocket(key)
socket.addEventListener('message', (event) => next(null, event.data))
socket.addEventListener('error', (event) => next(event.error))
return () => socket.close()
})
if (error) return
failed to load
if (!data) return
loading...
return
hello {data}!
}
```
--------------------------------
### Define Cache Provider Interface
Source: https://github.com/vercel/swr-site/blob/main/content/docs/advanced/cache.es.mdx
TypeScript interface defining the expected methods for a SWR cache provider: get, set, delete, and keys.
```typescript
interface Cache {
get(key: string): Data | undefined
set(key: string, value: Data): void
delete(key: string): void
keys(): IterableIterator
}
```
--------------------------------
### Subscribe to Firestore Views
Source: https://github.com/vercel/swr-site/blob/main/content/docs/subscription.mdx
Example of using `useSWRSubscription` to subscribe to real-time view counts from a Firestore database. Ensure you have the latest SWR version (>= 2.1.0).
```tsx
import useSWRSubscription from 'swr/subscription'
function Post({ id }) {
const { data } = useSWRSubscription(['views', id], ([_, postId], { next }) => {
const ref = firebase.database().ref('views/' + postId)
ref.on('value',
snapshot => next(null, snapshot.data()),
err => next(err)
)
return () => ref.off()
})
return Your post has {data} views!
}
```
--------------------------------
### Import useSWRInfinite for SWR 0.x
Source: https://github.com/vercel/swr-site/blob/main/content/docs/pagination.mdx
Shows the correct import path for useSWRInfinite when using older versions of SWR (0.x).
```jsx
import { useSWRInfinite } from 'swr'
```
--------------------------------
### Pass objects as keys
Source: https://github.com/vercel/swr-site/blob/main/content/docs/arguments.mdx
Demonstrates passing objects as keys and chaining SWR hooks using object-based keys.
```js
const { data: user } = useSWR(['/api/user', token], fetchWithToken)
// ...and then pass it as an argument to another useSWR hook
const { data: orders } = useSWR(user ? ['/api/orders', user] : null, fetchWithUser)
```
```js
const { data: orders } = useSWR({ url: '/api/orders', args: user }, fetcher)
```
--------------------------------
### Implement Pagination with useSWRInfinite
Source: https://context7.com/vercel/swr-site/llms.txt
Uses useSWRInfinite to manage multiple pages of data. The getKey function handles both offset-based and cursor-based pagination logic.
```jsx
import useSWRInfinite from 'swr/infinite'
const fetcher = url => fetch(url).then(res => res.json())
// getKey function determines the key for each page
const getKey = (pageIndex, previousPageData) => {
// Reached the end (no more data)
if (previousPageData && !previousPageData.length) return null
// First page, no previousPageData
if (pageIndex === 0) return '/api/posts?limit=10'
// Return key for next page
return `/api/posts?limit=10&offset=${pageIndex * 10}`
}
// For cursor-based pagination
const getCursorKey = (pageIndex, previousPageData) => {
if (previousPageData && !previousPageData.nextCursor) return null
if (pageIndex === 0) return '/api/posts?limit=10'
return `/api/posts?limit=10&cursor=${previousPageData.nextCursor}`
}
function PostList() {
const {
data,
error,
isLoading,
isValidating,
mutate,
size,
setSize
} = useSWRInfinite(getKey, fetcher, {
initialSize: 1,
revalidateAll: false,
revalidateFirstPage: true,
persistSize: false,
parallel: false // Set true to fetch pages in parallel
})
// Flatten all pages into single array
const posts = data ? data.flat() : []
const isEmpty = data?.[0]?.length === 0
const isReachingEnd = isEmpty || (data && data[data.length - 1]?.length < 10)
const isLoadingMore = isLoading || (size > 0 && data && typeof data[size - 1] === 'undefined')
if (error) return
Error loading posts
if (isLoading) return
Loading...
return (
Showing {posts.length} posts
{posts.map(post => (
{post.title}
{post.excerpt}
))}
)
}
```
--------------------------------
### Mutate Multiple Cache Items by Array Key Prefix
Source: https://github.com/vercel/swr-site/blob/main/content/docs/mutation.mdx
This example demonstrates mutating multiple cache entries where keys are arrays, specifically targeting keys where the first element is 'item'.
```jsx
useSWR(['item', 123], ...)
useSWR(['item', 124], ...)
useSWR(['item', 125], ...)
mutate(
key => Array.isArray(key) && key[0] === 'item',
undefined,
{ revalidate: false }
)
```
--------------------------------
### Implement basic pagination with useSWR
Source: https://github.com/vercel/swr-site/blob/main/content/docs/pagination.mdx
Use a React state variable to track the current page index and update the SWR key dynamically.
```jsx
function App () {
const [pageIndex, setPageIndex] = useState(0);
// The API URL includes the page index, which is a React state.
const { data } = useSWR(`/api/data?page=${pageIndex}`, fetcher);
// ... handle loading and error states
return
{data.map(item =>
{item.name}
)}
}
```
--------------------------------
### Update useSWRInfinite Imports
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v1.es.mdx
Update import paths for the useSWRInfinite hook and its associated types to the swr/infinite entry point.
```diff
- import { useSWRInfinite } from 'swr'
+ import useSWRInfinite from 'swr/infinite'
```
```diff
- import { SWRInfiniteConfiguration, SWRInfiniteResponse } from 'swr'
+ import { SWRInfiniteConfiguration, SWRInfiniteResponse } from 'swr/infinite'
```
--------------------------------
### Configure Default Fetcher with SWRConfig
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v1.mdx
SWR no longer provides a default fetcher. Configure a global fetcher using the `` component or provide it directly to `useSWR`.
```jsx
fetch(url).then(res => res.json()) }}>
```
```javascript
useSWR(key, (url) => fetch(url).then(res => res.json()))
```
--------------------------------
### Configure Default Fetcher
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v1.es.mdx
Provide a custom fetcher globally via SWRConfig or locally within the useSWR hook, as there is no longer a default fetcher.
```jsx
fetch(url).then(res => res.json()) }}>
// ... or
useSWR(key, (url) => fetch(url).then(res => res.json()))
```
--------------------------------
### Clear All SWR Cache Data Using Mutate
Source: https://github.com/vercel/swr-site/blob/main/content/docs/advanced/cache.es.mdx
Use the `mutate` function from `useSWRConfig` to clear all cache data. This example targets all cache keys and sets their data to undefined without triggering a revalidation.
```jsx
const { mutate } = useSWRConfig()
mutate(
key => true, // which cache keys are updated
undefined, // update cache data to `undefined`
{ revalidate: false } // do not revalidate
)
```
--------------------------------
### Handle multiple arguments
Source: https://github.com/vercel/swr-site/blob/main/content/docs/arguments.mdx
Shows the incorrect approach using a closure and the correct approach using an array as the key to ensure cache consistency.
```js
useSWR('/api/user', url => fetchWithToken(url, token))
```
```js
const { data: user } = useSWR(['/api/user', token], ([url, token]) => fetchWithToken(url, token))
```
--------------------------------
### Conditionally fetch data with SWR
Source: https://github.com/vercel/swr-site/blob/main/content/docs/conditional-fetching.mdx
Use null or a function returning a falsy value as the key to prevent SWR from starting a request. Throwing an error within the key function also halts the request.
```js
// conditionally fetch
const { data } = useSWR(shouldFetch ? '/api/data' : null, fetcher)
// ...or return a falsy value
const { data } = useSWR(() => shouldFetch ? '/api/data' : null, fetcher)
// ...or throw an error when user.id is not defined
const { data } = useSWR(() => '/api/data?uid=' + user.id, fetcher)
```
--------------------------------
### Pre-rendering with getStaticProps
Source: https://github.com/vercel/swr-site/blob/main/content/docs/with-nextjs.es.mdx
Uses SWRConfig to inject pre-fetched data into SWR hooks during static generation.
```jsx
export async function getStaticProps () {
// `getStaticProps` is executed on the server side.
const article = await getArticleFromAPI()
return {
props: {
fallback: {
'/api/article': article
}
}
}
}
function Article() {
// `data` will always be available as it's in `fallback`.
const { data } = useSWR('/api/article', fetcher)
return
{data.title}
}
export default function Page({ fallback }) {
// SWR hooks inside the `SWRConfig` boundary will use those values.
return (
)
}
```
--------------------------------
### Enable Parallel Fetching in useSWRInfinite
Source: https://github.com/vercel/swr-site/blob/main/content/docs/pagination.mdx
Set the `parallel` option to `true` to fetch pages independently and in parallel. This can significantly speed up loading when pages are not interdependent. Note that `previousPageData` will be `null` when `parallel` is enabled.
```jsx
// parallel = false (default)
// page1 ===> page2 ===> page3 ===> done
//
// parallel = true
// page1 ==> done
// page2 =====> done
// page3 ===> done
//
// previousPageData is always `null`
const getKey = (pageIndex, previousPageData) => {
return `/users?page=${pageIndex}&limit=10`
}
function App () {
const { data } = useSWRInfinite(getKey, fetcher, { parallel: true })
}
```
--------------------------------
### App Component with useSWRInfinite for Index Based Pagination
Source: https://github.com/vercel/swr-site/blob/main/content/docs/pagination.mdx
A React component demonstrating how to use `useSWRInfinite` with an index-based API. It fetches user data, calculates the total number of users, and provides a 'Load More' button.
```jsx
function App () {
const { data, size, setSize } = useSWRInfinite(getKey, fetcher)
if (!data) return 'loading'
// We can now calculate the number of all users
let totalUsers = 0
for (let i = 0; i < data.length; i++) {
totalUsers += data[i].length
}
return
{totalUsers} users listed
{data.map((users, index) => {
// `data` is an array of each page's API response.
return users.map(user =>
{user.name}
)
})}
}
```
--------------------------------
### Configure SWR with a Custom Map Cache Provider
Source: https://github.com/vercel/swr-site/blob/main/content/docs/advanced/cache.es.mdx
Example of configuring SWR to use a JavaScript Map instance as its cache provider within an SWRConfig boundary. This ensures all SWR hooks within the component tree use this specific Map for caching.
```jsx
import useSWR, { SWRConfig } from 'swr'
function App() {
return (
new Map() }}>
)
}
```
--------------------------------
### Use useSWRMutation for Declarative Data Mutations
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v2.ko.mdx
Use `useSWRMutation` to declaratively set up remote data mutations. It returns a `trigger` function to initiate the mutation manually, unlike `useSWR` which starts requests on render. The `isMutating` state indicates the mutation's progress.
```jsx
import useSWRMutation from 'swr/mutation'
async function sendRequest(url, { arg }) {
return fetch(url, {
method: 'POST',
body: JSON.stringify(arg)
})
}
function App() {
const { trigger, isMutating } = useSWRMutation('/api/user', sendRequest)
return (
)
}
```
--------------------------------
### Configure Middleware with SWRConfig or useSWR
Source: https://github.com/vercel/swr-site/blob/main/content/docs/middleware.es.mdx
Pass an array of middleware functions to the 'use' option in SWRConfig for global application or directly in useSWR for specific hooks.
```jsx
```
```jsx
useSWR(key, fetcher, { use: [myMiddleware] })
```
--------------------------------
### useSWRInfinite API
Source: https://github.com/vercel/swr-site/blob/main/content/docs/pagination.mdx
The useSWRInfinite hook provides functionality for fetching multiple pages of data. It accepts a getKey function, a fetcher function, and options, returning data, error, loading states, and pagination controls.
```APIDOC
## useSWRInfinite API
### Description
Provides the ability to trigger a number of requests with one hook for infinite loading scenarios.
### Parameters
- `getKey` (function): A function that accepts the index and the previous page data, and returns the key for a page. If `null` is returned, the request for that page will not start.
- `fetcher` (function): Same as `useSWR`'s fetcher function.
- `options` (object): Accepts all options supported by `useSWR`, with 4 extra options:
- `initialSize` (number): Defaults to 1. The number of pages to load initially. This option is not allowed to change in the lifecycle.
- `revalidateAll` (boolean): Defaults to `false`. If `true`, always try to revalidate all pages.
- `revalidateFirstPage` (boolean): Defaults to `true`. If `true`, always try to revalidate the first page.
- `persistSize` (boolean): Defaults to `false`. If `true`, the page size is not reset to 1 (or `initialSize` if set) when the first page's key changes.
- `parallel` (boolean): Defaults to `false`. If `true`, fetches multiple pages in parallel.
### Return Values
- `data` (array): An array of fetch response values for each page. The structure is `[[page1_data], [page2_data], ...]`.
- `error` (any): Same as `useSWR`'s `error`.
- `isLoading` (boolean): Same as `useSWR`'s `isLoading`.
- `isValidating` (boolean): Same as `useSWR`'s `isValidating`.
- `mutate` (function): Same as `useSWR`'s bound mutate function but manipulates the data array.
- `size` (number): The number of pages that will be fetched and returned.
- `setSize` (function): A function to set the number of pages that need to be fetched.
```
--------------------------------
### HTML Link Preload for Top-Level Data
Source: https://github.com/vercel/swr-site/blob/main/content/docs/prefetching.mdx
Use `rel="preload"` in your HTML `` to prefetch data when the HTML loads, even before JavaScript. This is efficient for top-level requests.
```html
```
--------------------------------
### Globally Enable Key Serialization with SWRConfig
Source: https://github.com/vercel/swr-site/blob/main/content/docs/middleware.es.mdx
Configure SWR globally to use the serialize middleware for all SWR hooks by providing it in the SWRConfig value.
```jsx
```
--------------------------------
### Pre-rendering with getStaticProps and SWR Fallback
Source: https://github.com/vercel/swr-site/blob/main/content/docs/with-nextjs.mdx
Use `getStaticProps` to pre-render a page and provide initial data via `fallback` in `SWRConfig`. The `Article` component will render pre-generated data first, then fetch the latest data after hydration.
```jsx
export async function getStaticProps () {
// `getStaticProps` is executed on the server side.
const article = await getArticleFromAPI()
return {
props: {
fallback: {
'/api/article': article
}
}
}
}
function Article() {
// `data` will always be available as it's in `fallback`.
const { data } = useSWR('/api/article', fetcher)
return
{data.title}
}
export default function Page({ fallback }) {
// SWR hooks inside the `SWRConfig` boundary will use those values.
return (
)
}
```
--------------------------------
### Typing useSWRSubscription with Options
Source: https://github.com/vercel/swr-site/blob/main/content/docs/typescript.es.mdx
Shows how to manually specify the type of the `next` callback argument within `SWRSubscriptionOptions` for `useSWRSubscription`.
```typescript
import useSWRSubscription from 'swr/subscription'
import type { SWRSubscriptionOptions } from 'swr/subscription'
const { data, error } = useSWRSubscription('key',
(key, { next }: SWRSubscriptionOptions) => {
//^ key will be inferred as `string`
//....
})
return {
data,
//^ data will be inferred as `number | undefined`
error
//^ error will be inferred as `Error | undefined`
}
}
```
--------------------------------
### Configure Fallback Data with SWRConfig
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v1.es.mdx
Provide pre-fetched data as initial values for SWR hooks using the `fallback` option within `SWRConfig`. This is useful for SSG, SSR, and testing.
```jsx
```
--------------------------------
### Prefetch Data in Server Components with SWRConfig
Source: https://github.com/vercel/swr-site/blob/main/content/docs/with-nextjs.es.mdx
Initiate data fetching on the server in React Server Components and pass the resulting promises to client components via the `` provider's `fallback` option. This allows SWR to resolve promises during SSR.
```tsx
import { SWRConfig } from 'swr'
export default async function Layout({ children }: { children: React.ReactNode }) {
// Initiate the data fetching on the server side.
const userPromise = fetchUserFromAPI()
const postsPromise = fetchPostsFromAPI()
return (
{children}
)
}
```
--------------------------------
### Preload data with SWR
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v2.ko.mdx
Use the preload API to fetch resources early, which useSWR will reuse if the request is still ongoing.
```jsx
import useSWR, { preload } from 'swr'
const fetcher = (url) => fetch(url).then((res) => res.json())
// You can call the preload function in anywhere
preload('/api/user', fetcher)
function Profile() {
// The component that actually uses the data:
const { data, error } = useSWR('/api/user', fetcher)
// ...
}
export function Page () {
return
}
```
--------------------------------
### Wrap components with SWRConfig
Source: https://github.com/vercel/swr-site/blob/main/content/docs/global-configuration.mdx
Use SWRConfig to provide global configuration options to all child SWR hooks.
```jsx
```
--------------------------------
### Apply Middleware with SWRConfig or useSWR
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v1.es.mdx
Extend SWR's functionality by applying middleware globally via `SWRConfig` or locally to a specific hook instance. Middleware can be used for logging, caching strategies, and more.
```jsx
// ... or directly in `useSWR`:
useSWR(key, fetcher, { use: [...middleware] })
```
--------------------------------
### Programmatic Data Prefetching with SWR `preload` API
Source: https://github.com/vercel/swr-site/blob/main/content/docs/prefetching.mdx
Prefetch resources programmatically using the `preload` API, which accepts a `key` and a `fetcher`. This can be called outside of React components to prevent potential waterfalls.
```jsx
import { useState } from 'react'
import useSWR, { preload } from 'swr'
const fetcher = (url) => fetch(url).then((res) => res.json())
// Preload the resource before rendering the User component below,
// this prevents potential waterfalls in your application.
// You can also start preloading when hovering the button or link, too.
preload('/api/user', fetcher)
function User() {
const { data } = useSWR('/api/user', fetcher)
...
}
export default function App() {
const [show, setShow] = useState(false)
return (
{show ? : null}
)
}
```
--------------------------------
### Use Hook-Returned Mutate with useSWRConfig
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v1.mdx
It is now recommended to use the `mutate` function returned by the `useSWRConfig` hook instead of importing it globally. This ensures proper cache management, especially when using cache providers.
```diff
- import { mutate } from 'swr'
+ import { useSWRConfig } from 'swr'
```
```javascript
function Foo () {
const { mutate } = useSWRConfig()
return
}
```
--------------------------------
### Chaining Middleware Configuration
Source: https://github.com/vercel/swr-site/blob/main/content/docs/middleware.es.mdx
Middleware options are extended like regular options. Nested SWRConfig providers with 'use' options will merge their middleware arrays.
```jsx
function Bar () {
useSWR(key, fetcher, { use: [c] })
// ...
}
function Foo() {
return (
)
}
```
```js
useSWR(key, fetcher, { use: [a, b, c] })
```
--------------------------------
### Configure SWR Globally
Source: https://context7.com/vercel/swr-site/llms.txt
Use SWRConfig to provide default fetchers, error handlers, and fallback data to all hooks in the component tree. Nested providers can access and extend parent configurations.
```jsx
import useSWR, { SWRConfig } from 'swr'
// Global fetcher
const globalFetcher = async (url) => {
const res = await fetch(url, {
headers: { 'Authorization': `Bearer ${getToken()}` }
})
if (!res.ok) {
const error = new Error('API request failed')
error.status = res.status
error.info = await res.json()
throw error
}
return res.json()
}
function App() {
return (
{
if (error.status === 401) {
redirectToLogin()
}
console.error(`SWR Error [${key}]:`, error)
},
// Global success handler
onSuccess: (data, key) => {
console.log(`SWR Success [${key}]`)
},
// Fallback data for SSR/SSG
fallback: {
'/api/config': { theme: 'light', locale: 'en' }
}
}}
>
)
}
// Nested configuration (merges with parent)
function AdminSection() {
return (
({
...parentConfig,
refreshInterval: 5000, // Override for admin section
fetcher: (url) => parentConfig.fetcher(url, { admin: true })
})}
>
)
}
```
--------------------------------
### Optimistic Updates with useSWRMutation
Source: https://github.com/vercel/swr-site/blob/main/content/docs/mutation.es.mdx
Demonstrates how to configure optimistic data updates either globally in the hook options or specifically when calling the `trigger` function.
```jsx
const { trigger } = useSWRMutation('/api/user', updateUser, {
optimisticData: current => ({ ...current, name: newName })
})
// or
trigger(newName, {
optimisticData: current => ({ ...current, name: newName })
})
```
--------------------------------
### Perform basic mutation with request body
Source: https://github.com/vercel/swr-site/blob/main/content/docs/mutation.mdx
Shows how to pass a request body to the fetcher and handle the mutation result using the trigger function.
```tsx
import useSWRMutation from 'swr/mutation'
async function sendRequest(url, { arg }: { arg: { username: string }}) {
return fetch(url, {
method: 'POST',
body: JSON.stringify(arg)
}).then(res => res.json())
}
function App() {
const { trigger, isMutating } = useSWRMutation('/api/user', sendRequest, /* options */)
return (
)
}
```
--------------------------------
### Extend SWR Configurations with Functions
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v2.es.mdx
Configure SWR dynamically by providing a function to the `value` prop of `SWRConfig`. This function receives the parent configuration and returns a new one, allowing for flexible configuration inheritance in large codebases.
```jsx
({
dedupingInterval: parentConfig.dedupingInterval * 5,
refreshInterval: 100,
})}>
```
--------------------------------
### Displaying Loading and Revalidation States with SWR
Source: https://github.com/vercel/swr-site/blob/main/content/docs/advanced/understanding.es.mdx
Uses isLoading to show a skeleton during initial load and isValidating to show a spinner during background revalidations.
```jsx
function Stock() {
const { data, isLoading, isValidating } = useSWR(STOCK_API, fetcher, {
refreshInterval: 3000
});
// If it's still loading the initial data, there is nothing to display.
// We return a skeleton here.
if (isLoading) return ;
// Otherwise, display the data and a spinner that indicates a background
// revalidation.
return (
<>
${data}
{isValidating ? : null}
>
);
}
```
--------------------------------
### Implement SWR Middleware
Source: https://context7.com/vercel/swr-site/llms.txt
Create custom middleware functions to intercept SWR hooks and apply logic like logging or data persistence. Use the 'use' property in SWRConfig or individual useSWR hooks to apply them.
```jsx
import useSWR, { SWRConfig } from 'swr'
// Logger middleware
function logger(useSWRNext) {
return (key, fetcher, config) => {
const extendedFetcher = async (...args) => {
console.log(`[SWR] Fetching: ${key}`)
const start = Date.now()
try {
const result = await fetcher(...args)
console.log(`[SWR] Success: ${key} (${Date.now() - start}ms)`)
return result
} catch (error) {
console.error(`[SWR] Error: ${key}`, error)
throw error
}
}
return useSWRNext(key, extendedFetcher, config)
}
}
// Laggy data middleware - keep previous data while loading new key
function laggy(useSWRNext) {
return (key, fetcher, config) => {
const laggyDataRef = useRef()
const swr = useSWRNext(key, fetcher, config)
useEffect(() => {
if (swr.data !== undefined) {
laggyDataRef.current = swr.data
}
}, [swr.data])
const dataOrLaggyData = swr.data === undefined ? laggyDataRef.current : swr.data
const isLagging = swr.data === undefined && laggyDataRef.current !== undefined
return {
...swr,
data: dataOrLaggyData,
isLagging
}
}
}
// Using middleware
function App() {
return (
)
}
function SearchComponent() {
const [query, setQuery] = useState('')
// Use laggy middleware for smooth transitions
const { data, isLagging } = useSWR(
query ? `/api/search?q=${query}` : null,
fetcher,
{ use: [laggy] }
)
return (
setQuery(e.target.value)} />
{isLagging && Loading new results...}
{data?.results.map(item =>
{item.title}
)}
)
}
```
--------------------------------
### useSWRMutation for Creating Users
Source: https://github.com/vercel/swr-site/blob/main/content/docs/mutation.es.mdx
Shows how to use useSWRMutation to send data to an API for user creation. The `isMutating` flag can be used to disable buttons during the request.
```tsx
import useSWRMutation from 'swr/mutation'
async function sendRequest(url, { arg }: { arg: { username: string } }) {
return fetch(url, {
method: 'POST',
body: JSON.stringify(arg)
}).then(res => res.json())
}
function App() {
const { trigger, isMutating } = useSWRMutation('/api/user', sendRequest, /* options */)
return (
)
}
```
--------------------------------
### Create a SWR Key Serialization Middleware
Source: https://github.com/vercel/swr-site/blob/main/content/docs/middleware.es.mdx
This middleware serializes array keys using JSON.stringify to ensure stable comparisons. It's useful for SWR versions older than 1.1.0.
```jsx
function serialize(useSWRNext) {
return (key, fetcher, config) => {
// Serialize the key.
const serializedKey = Array.isArray(key) ? JSON.stringify(key) : key
// Pass the serialized key, and unserialize it in fetcher.
return useSWRNext(serializedKey, (k) => fetcher(...JSON.parse(k)), config)
}
}
```
--------------------------------
### Access Global Configurations with useSWRConfig
Source: https://github.com/vercel/swr-site/blob/main/content/blog/swr-v1.es.mdx
Retrieve global configurations, including the cache provider and `mutate` function, using the `useSWRConfig` hook. This is useful for interacting with global SWR state.
```javascript
import { useSWRConfig } from 'swr'
function Foo () {
const { refreshInterval, cache, mutate, ...restConfig } = useSWRConfig()
// ...
}
```
--------------------------------
### Global SWR Configuration
Source: https://github.com/vercel/swr-site/blob/main/content/docs/advanced/react-native.mdx
Wrap your application with SWRConfig to set default configurations globally. This is useful for applying settings across your entire app.
```jsx
```