}>
+
+
+
+ )
+}
diff --git a/e2e/test/suspense-undefined-key.test.ts b/e2e/test/suspense-undefined-key.test.ts
new file mode 100644
index 000000000..c618a942c
--- /dev/null
+++ b/e2e/test/suspense-undefined-key.test.ts
@@ -0,0 +1,20 @@
+/* eslint-disable testing-library/prefer-screen-queries */
+import { test, expect } from '@playwright/test'
+
+test.describe('suspense with undefined key', () => {
+ test('should render correctly when key is undefined', async ({ page }) => {
+ await page.goto('./suspense-undefined-key', { waitUntil: 'commit' })
+
+ // Should show content for undefined key (not suspense)
+ await expect(page.getByText('empty')).toBeVisible()
+
+ // Click toggle to enable key
+ await page.getByRole('button', { name: 'toggle' }).click()
+
+ // Should show loading fallback when key becomes defined
+ await expect(page.getByText('fallback')).toBeVisible()
+
+ // Should eventually show the fetched data
+ await expect(page.getByText('SWR')).toBeVisible()
+ })
+})
diff --git a/src/index/use-swr.ts b/src/index/use-swr.ts
index eb6a2f480..fe535e794 100644
--- a/src/index/use-swr.ts
+++ b/src/index/use-swr.ts
@@ -714,14 +714,14 @@ export const useSWRHandler = (
// If there is no `error`, the `revalidation` promise needs to be thrown to
// the suspense boundary.
if (suspense) {
+ const hasKeyButNoData = key && isUndefined(data)
// SWR should throw when trying to use Suspense on the server with React 18,
// without providing any fallback data. This causes hydration errors. See:
// https://github.com/vercel/swr/issues/1832
- if (!IS_REACT_LEGACY && IS_SERVER) {
+ if (!IS_REACT_LEGACY && IS_SERVER && hasKeyButNoData) {
throw new Error('Fallback data is required when using Suspense in SSR.')
}
- const hasKeyButNoData = key && isUndefined(data)
// Always update fetcher and config refs even with the Suspense mode.
if (hasKeyButNoData) {
fetcherRef.current = fetcher