The SWR 2.0 release candidate. This RC has one breaking change, a new option for mutation APIs, and some bug fixes & improvements.
A failed mutation will not cause useSWR's error to be updated:
const { error, mutate } = useSWR('/api/user', getUser)
return <button onClick={async () => {
try {
await mutate(updateUser)
} catch (mutationError) {
// `mutationError` will not cause `error` to be updated.
}
}}>Update User</button>
In 2.0, with the example above, error will only be coming from getUser and will be shared across all useSWR('/api/user') hooks. And mutation errors (mutationError) will be coming from mutations like updateUser calls, they will be separated from fetcher errors.
There is also a new option throwOnError for useSWRMutation to disable the default throwing behavior of trigger:
const { trigger } = useSWRMutation('/api/user', updateUser)
try {
await trigger()
} catch (err) {
// ... it throws when failed to trigger the mutation so you can
// easily change the flow here
}
const { trigger, error } = useSWRMutation('/api/user', updateUser, {
throwOnError: false
})
// You don't need to try-catch here, you can instead handle errors
// on the component level in a declarative way
await trigger()
Read more about this change in #2182.
throwOnError option by @shuding in https://github.com/vercel/swr/pull/2182Full Changelog: https://github.com/vercel/swr/compare/2.0.0-beta.7...2.0.0-rc.0
Fetched April 18, 2026