From 5363216ea4673a47d69c261bd4b65b63d44aaea0 Mon Sep 17 00:00:00 2001 From: Hayden Bleasel Date: Wed, 10 Dec 2025 09:00:55 -0800 Subject: [PATCH 1/6] Migrate from swr repo --- README.md | 27 - .../(home)/components/centered-section.tsx | 26 + app/[lang]/(home)/components/cta.tsx | 19 + app/[lang]/(home)/components/hero.tsx | 29 + .../(home)/components/one-two-section.tsx | 25 + app/[lang]/(home)/components/templates.tsx | 50 + .../(home)/components/text-grid-section.tsx | 20 + app/[lang]/(home)/copy.ts | 468 ++ app/[lang]/(home)/layout.tsx | 14 + app/[lang]/(home)/page.tsx | 108 + app/[lang]/blog/[...slug]/page.tsx | 104 + app/[lang]/blog/layout.tsx | 10 + app/[lang]/docs/[[...slug]]/page.tsx | 104 + app/[lang]/docs/layout.tsx | 10 + app/[lang]/examples/[[...slug]]/page.tsx | 108 + app/[lang]/examples/layout.tsx | 10 + app/[lang]/layout.tsx | 29 + app/[lang]/llms.mdx/[[...slug]]/route.ts | 30 + app/[lang]/llms.txt/route.ts | 15 + app/[lang]/og/[...slug]/background.png | Bin 0 -> 20702 bytes .../og/[...slug]/geist-sans-regular.ttf | Bin 0 -> 103636 bytes .../og/[...slug]/geist-sans-semibold.ttf | Bin 0 -> 105492 bytes app/[lang]/og/[...slug]/route.tsx | 95 + app/[lang]/rss.xml/route.ts | 46 + app/actions/feedback/emotions.ts | 18 + app/actions/feedback/index.ts | 43 + app/api/chat/route.ts | 116 + app/api/chat/tools.ts | 222 + app/api/chat/types.ts | 26 + app/api/chat/utils.ts | 56 + app/api/search/route.ts | 51 + app/favicon.ico | Bin 0 -> 25931 bytes app/global.css | 6 + app/styles/geistdocs.css | 196 + components.json | 22 + components/ai-elements/code-block.tsx | 178 + components/ai-elements/conversation.tsx | 100 + components/ai-elements/message.tsx | 448 ++ components/ai-elements/open-in-chat.tsx | 365 ++ components/ai-elements/prompt-input.tsx | 1377 ++++++ components/ai-elements/shimmer.tsx | 64 + components/ai-elements/sources.tsx | 77 + components/ai-elements/suggestion.tsx | 56 + components/blog-index.js | 39 - components/{authors.js => custom/authors.tsx} | 22 +- components/custom/bleed.tsx | 23 + .../cache.js => custom/diagrams/cache.tsx} | 16 +- .../diagrams/infinite.tsx} | 16 +- .../diagrams/pagination.tsx} | 18 +- .../diagrams/welcome.tsx} | 16 +- .../excalidraw/state-machine.excalidraw | 0 components/{logo.js => custom/logo.tsx} | 5 +- components/features.js | 51 - components/features.module.css | 45 - components/geistdocs/ask-ai.tsx | 33 + components/geistdocs/callout.tsx | 40 + components/geistdocs/chat.tsx | 407 ++ components/geistdocs/code-block-tabs.tsx | 61 + components/geistdocs/code-block.tsx | 125 + components/geistdocs/copy-chat.tsx | 56 + components/geistdocs/copy-page.tsx | 27 + components/geistdocs/desktop-menu.tsx | 52 + components/geistdocs/docs-layout.tsx | 47 + components/geistdocs/docs-page.tsx | 35 + components/geistdocs/edit-source.tsx | 30 + components/geistdocs/feedback.tsx | 139 + components/geistdocs/footer.tsx | 28 + components/geistdocs/github-button.tsx | 19 + components/geistdocs/home-layout.tsx | 46 + components/geistdocs/icons.tsx | 13 + components/geistdocs/installer.tsx | 58 + components/geistdocs/language-selector.tsx | 43 + components/geistdocs/mdx-components.tsx | 59 + components/geistdocs/mermaid.tsx | 68 + components/geistdocs/message-metadata.tsx | 84 + components/geistdocs/mobile-menu.tsx | 20 + components/geistdocs/navbar.tsx | 30 + components/geistdocs/open-in-chat.tsx | 49 + components/geistdocs/provider.tsx | 61 + components/geistdocs/rss-button.tsx | 10 + components/geistdocs/scroll-top.tsx | 21 + components/geistdocs/search.tsx | 78 + components/geistdocs/sidebar.tsx | 116 + components/geistdocs/theme-toggle.tsx | 20 + components/geistdocs/video.tsx | 16 + components/icons/backend-agnostic.js | 23 - components/icons/lightweight.js | 18 - components/icons/pagination.js | 18 - components/icons/realtime.js | 17 - components/icons/remote-local.js | 18 - components/icons/rendering-strategies.js | 17 - components/icons/suspense.js | 18 - components/icons/typescript.js | 18 - .../translations/svgs.ts | 124 +- components/ui/accordion.tsx | 66 + components/ui/alert-dialog.tsx | 157 + components/ui/alert.tsx | 66 + components/ui/aspect-ratio.tsx | 11 + components/ui/avatar.tsx | 53 + components/ui/badge.tsx | 46 + components/ui/breadcrumb.tsx | 109 + components/ui/button-group.tsx | 83 + components/ui/button.tsx | 60 + components/ui/calendar.tsx | 216 + components/ui/card.tsx | 92 + components/ui/carousel.tsx | 241 ++ components/ui/chart.tsx | 357 ++ components/ui/checkbox.tsx | 32 + components/ui/collapsible.tsx | 33 + components/ui/command.tsx | 184 + components/ui/context-menu.tsx | 252 ++ components/ui/dialog.tsx | 143 + components/ui/drawer.tsx | 135 + components/ui/dropdown-menu.tsx | 257 ++ components/ui/empty.tsx | 104 + components/ui/field.tsx | 248 ++ components/ui/form.tsx | 167 + components/ui/hover-card.tsx | 44 + components/ui/input-group.tsx | 170 + components/ui/input-otp.tsx | 77 + components/ui/input.tsx | 21 + components/ui/item.tsx | 193 + components/ui/kbd.tsx | 28 + components/ui/label.tsx | 24 + components/ui/menubar.tsx | 276 ++ components/ui/navigation-menu.tsx | 168 + components/ui/pagination.tsx | 127 + components/ui/popover.tsx | 48 + components/ui/progress.tsx | 31 + components/ui/radio-group.tsx | 45 + components/ui/resizable.tsx | 56 + components/ui/scroll-area.tsx | 58 + components/ui/select.tsx | 187 + components/ui/separator.tsx | 28 + components/ui/sheet.tsx | 139 + components/ui/sidebar.tsx | 726 ++++ components/ui/skeleton.tsx | 13 + components/ui/slider.tsx | 63 + components/ui/sonner.tsx | 40 + components/ui/spinner.tsx | 16 + components/ui/switch.tsx | 31 + components/ui/table.tsx | 116 + components/ui/tabs.tsx | 66 + components/ui/textarea.tsx | 18 + components/ui/toggle-group.tsx | 83 + components/ui/toggle.tsx | 47 + components/ui/tooltip.tsx | 61 + components/use-locales-map.js | 78 - components/vercel.js | 10 - components/video.js | 69 - .../blog/swr-v1.cn.mdx | 15 +- .../blog/swr-v1.es.mdx | 15 +- .../blog/swr-v1.fr.mdx | 16 +- {pages => content}/blog/swr-v1.ja.mdx | 15 +- {pages => content}/blog/swr-v1.ko.mdx | 15 +- .../blog/swr-v1.mdx | 15 +- .../blog/swr-v1.pt.mdx | 453 +- {pages => content}/blog/swr-v1.ru.mdx | 15 +- .../blog/swr-v2.cn.mdx | 16 +- .../blog/swr-v2.es.mdx | 13 +- .../blog/swr-v2.fr.mdx | 14 +- {pages => content}/blog/swr-v2.ja.mdx | 15 +- {pages => content}/blog/swr-v2.ko.mdx | 13 +- .../blog/swr-v2.mdx | 13 +- .../blog/swr-v2.pt.mdx | 13 +- {pages => content}/blog/swr-v2.ru.mdx | 13 +- .../docs/advanced/cache.cn.mdx | 8 +- .../docs/advanced/cache.es.mdx | 8 +- .../docs/advanced/cache.fr.mdx | 8 +- {pages => content}/docs/advanced/cache.ja.mdx | 8 +- {pages => content}/docs/advanced/cache.ko.mdx | 8 +- .../docs/advanced/cache.mdx | 8 +- .../docs/advanced/cache.pt.mdx | 8 +- {pages => content}/docs/advanced/cache.ru.mdx | 8 +- .../docs/advanced/devtools.cn.mdx | 7 +- .../docs/advanced/devtools.es.mdx | 7 +- .../docs/advanced/devtools.fr.mdx | 6 +- .../docs/advanced/devtools.ja.mdx | 7 +- .../docs/advanced/devtools.ko.mdx | 6 +- .../docs/advanced/devtools.mdx | 8 +- .../docs/advanced/devtools.pt.mdx | 6 +- .../docs/advanced/devtools.ru.mdx | 7 +- .../docs/advanced/performance.cn.mdx | 4 +- .../docs/advanced/performance.es.mdx | 4 +- .../docs/advanced/performance.fr.mdx | 4 +- .../docs/advanced/performance.ja.mdx | 4 +- .../docs/advanced/performance.ko.mdx | 4 +- .../docs/advanced/performance.mdx | 4 +- .../docs/advanced/performance.pt.mdx | 4 +- .../docs/advanced/performance.ru.mdx | 4 +- .../docs/advanced/react-native.cn.mdx | 6 +- .../docs/advanced/react-native.es.mdx | 6 +- .../docs/advanced/react-native.fr.mdx | 6 +- .../docs/advanced/react-native.ja.mdx | 6 +- .../docs/advanced/react-native.ko.mdx | 9 +- .../docs/advanced/react-native.mdx | 6 +- .../docs/advanced/react-native.pt.mdx | 186 +- .../docs/advanced/react-native.ru.mdx | 6 +- .../docs/advanced/understanding.cn.mdx | 9 +- .../docs/advanced/understanding.es.mdx | 7 +- .../docs/advanced/understanding.fr.mdx | 7 +- .../docs/advanced/understanding.ja.mdx | 7 +- .../docs/advanced/understanding.ko.mdx | 7 +- .../docs/advanced/understanding.mdx | 7 +- .../docs/advanced/understanding.pt.mdx | 7 +- .../docs/advanced/understanding.ru.mdx | 7 +- .../api.zh-CN.mdx => content/docs/api.cn.mdx | 6 +- .../api.es-ES.mdx => content/docs/api.es.mdx | 6 +- .../api.fr-FR.mdx => content/docs/api.fr.mdx | 6 +- {pages => content}/docs/api.ja.mdx | 6 +- {pages => content}/docs/api.ko.mdx | 6 +- .../api.en-US.mdx => content/docs/api.mdx | 7 +- .../api.pt-BR.mdx => content/docs/api.pt.mdx | 6 +- {pages => content}/docs/api.ru.mdx | 6 +- .../docs/arguments.cn.mdx | 6 +- .../docs/arguments.es.mdx | 6 +- .../docs/arguments.fr.mdx | 7 +- {pages => content}/docs/arguments.ja.mdx | 6 +- {pages => content}/docs/arguments.ko.mdx | 6 +- .../docs/arguments.mdx | 7 +- .../docs/arguments.pt.mdx | 6 +- {pages => content}/docs/arguments.ru.mdx | 6 +- .../docs/conditional-fetching.cn.mdx | 4 +- .../docs/conditional-fetching.es.mdx | 5 +- .../docs/conditional-fetching.fr.mdx | 4 +- .../docs/conditional-fetching.ja.mdx | 4 +- .../docs/conditional-fetching.ko.mdx | 4 +- .../docs/conditional-fetching.mdx | 4 +- .../docs/conditional-fetching.pt.mdx | 72 +- .../docs/conditional-fetching.ru.mdx | 4 +- .../docs/data-fetching.cn.mdx | 7 +- .../docs/data-fetching.es.mdx | 7 +- .../docs/data-fetching.fr.mdx | 7 +- {pages => content}/docs/data-fetching.ja.mdx | 7 +- {pages => content}/docs/data-fetching.ko.mdx | 7 +- .../docs/data-fetching.mdx | 7 +- .../docs/data-fetching.pt.mdx | 147 +- {pages => content}/docs/data-fetching.ru.mdx | 7 +- .../docs/error-handling.cn.mdx | 7 +- .../docs/error-handling.es.mdx | 7 +- .../docs/error-handling.fr.mdx | 7 +- {pages => content}/docs/error-handling.ja.mdx | 7 +- {pages => content}/docs/error-handling.ko.mdx | 7 +- .../docs/error-handling.mdx | 7 +- .../docs/error-handling.pt.mdx | 7 +- {pages => content}/docs/error-handling.ru.mdx | 7 +- .../docs/getting-started.cn.mdx | 30 +- .../docs/getting-started.es.mdx | 29 +- .../docs/getting-started.fr.mdx | 29 +- .../docs/getting-started.ja.mdx | 29 +- .../docs/getting-started.ko.mdx | 29 +- .../docs/getting-started.mdx | 29 +- .../docs/getting-started.pt.mdx | 29 +- .../docs/getting-started.ru.mdx | 29 +- .../docs/global-configuration.cn.mdx | 4 +- .../docs/global-configuration.es.mdx | 4 +- .../docs/global-configuration.fr.mdx | 4 +- .../docs/global-configuration.ja.mdx | 5 +- .../docs/global-configuration.ko.mdx | 4 +- .../docs/global-configuration.mdx | 4 +- .../docs/global-configuration.pt.mdx | 5 +- .../docs/global-configuration.ru.mdx | 4 +- content/docs/meta.json | 9 + .../docs/middleware.cn.mdx | 7 +- .../docs/middleware.es.mdx | 6 +- .../docs/middleware.fr.mdx | 6 +- {pages => content}/docs/middleware.ja.mdx | 6 +- {pages => content}/docs/middleware.ko.mdx | 7 +- .../docs/middleware.mdx | 6 +- .../docs/middleware.pt.mdx | 408 +- {pages => content}/docs/middleware.ru.mdx | 6 +- .../docs/mutation.cn.mdx | 6 +- .../docs/mutation.es.mdx | 7 +- .../docs/mutation.fr.mdx | 6 +- {pages => content}/docs/mutation.ja.mdx | 7 +- {pages => content}/docs/mutation.ko.mdx | 6 +- .../docs/mutation.mdx | 6 +- .../docs/mutation.pt.mdx | 6 +- {pages => content}/docs/mutation.ru.mdx | 7 +- .../docs/pagination.cn.mdx | 10 +- .../docs/pagination.es.mdx | 10 +- .../docs/pagination.fr.mdx | 8 +- {pages => content}/docs/pagination.ja.mdx | 10 +- {pages => content}/docs/pagination.ko.mdx | 10 +- .../docs/pagination.mdx | 10 +- .../docs/pagination.pt.mdx | 11 +- {pages => content}/docs/pagination.ru.mdx | 10 +- .../docs/prefetching.cn.mdx | 4 +- .../docs/prefetching.es.mdx | 4 +- .../docs/prefetching.fr.mdx | 4 +- {pages => content}/docs/prefetching.ja.mdx | 4 +- {pages => content}/docs/prefetching.ko.mdx | 5 +- .../docs/prefetching.mdx | 4 +- .../docs/prefetching.pt.mdx | 4 +- {pages => content}/docs/prefetching.ru.mdx | 4 +- .../docs/revalidation.cn.mdx | 9 +- .../docs/revalidation.es.mdx | 9 +- .../docs/revalidation.fr.mdx | 9 +- {pages => content}/docs/revalidation.ja.mdx | 9 +- {pages => content}/docs/revalidation.ko.mdx | 9 +- .../docs/revalidation.mdx | 9 +- .../docs/revalidation.pt.mdx | 9 +- {pages => content}/docs/revalidation.ru.mdx | 9 +- .../docs/subscription.cn.mdx | 7 +- .../docs/subscription.es.mdx | 6 +- .../docs/subscription.fr.mdx | 6 +- {pages => content}/docs/subscription.ja.mdx | 8 +- {pages => content}/docs/subscription.ko.mdx | 6 +- .../docs/subscription.mdx | 8 +- .../docs/subscription.pt.mdx | 8 +- {pages => content}/docs/subscription.ru.mdx | 6 +- .../docs/suspense.cn.mdx | 6 +- .../docs/suspense.es.mdx | 6 +- .../docs/suspense.fr.mdx | 6 +- {pages => content}/docs/suspense.ja.mdx | 6 +- {pages => content}/docs/suspense.ko.mdx | 6 +- .../docs/suspense.mdx | 6 +- .../docs/suspense.pt.mdx | 6 +- {pages => content}/docs/suspense.ru.mdx | 6 +- .../docs/typescript.cn.mdx | 4 +- .../docs/typescript.es.mdx | 4 +- .../docs/typescript.fr.mdx | 5 +- {pages => content}/docs/typescript.ja.mdx | 4 +- {pages => content}/docs/typescript.ko.mdx | 5 +- .../docs/typescript.mdx | 7 +- .../docs/typescript.pt.mdx | 4 +- {pages => content}/docs/typescript.ru.mdx | 4 +- .../docs/with-nextjs.cn.mdx | 6 +- .../docs/with-nextjs.es.mdx | 6 +- .../docs/with-nextjs.fr.mdx | 6 +- {pages => content}/docs/with-nextjs.ja.mdx | 6 +- {pages => content}/docs/with-nextjs.ko.mdx | 6 +- .../docs/with-nextjs.mdx | 6 +- .../docs/with-nextjs.pt.mdx | 308 +- {pages => content}/docs/with-nextjs.ru.mdx | 6 +- .../examples/auth.cn.mdx | 0 .../examples/auth.es.mdx | 0 .../examples/auth.fr.mdx | 0 {pages => content}/examples/auth.ja.mdx | 0 {pages => content}/examples/auth.ko.mdx | 0 .../examples/auth.mdx | 0 .../examples/auth.pt.mdx | 0 {pages => content}/examples/auth.ru.mdx | 0 .../examples/basic.cn.mdx | 0 .../examples/basic.es.mdx | 0 .../examples/basic.fr.mdx | 0 {pages => content}/examples/basic.ja.mdx | 0 {pages => content}/examples/basic.ko.mdx | 0 .../examples/basic.mdx | 0 .../examples/basic.pt.mdx | 0 {pages => content}/examples/basic.ru.mdx | 0 .../examples/error-handling.cn.mdx | 0 .../examples/error-handling.es.mdx | 0 .../examples/error-handling.fr.mdx | 0 .../examples/error-handling.ja.mdx | 0 .../examples/error-handling.ko.mdx | 0 .../examples/error-handling.mdx | 0 .../examples/error-handling.pt.mdx | 0 .../examples/error-handling.ru.mdx | 0 .../examples/infinite-loading.cn.mdx | 0 .../examples/infinite-loading.es.mdx | 0 .../examples/infinite-loading.fr.mdx | 0 .../examples/infinite-loading.ja.mdx | 0 .../examples/infinite-loading.ko.mdx | 0 .../examples/infinite-loading.mdx | 0 .../examples/infinite-loading.pt.mdx | 0 .../examples/infinite-loading.ru.mdx | 0 .../examples/optimistic-ui.cn.mdx | 0 .../examples/optimistic-ui.es.mdx | 0 .../examples/optimistic-ui.fr.mdx | 0 .../examples/optimistic-ui.ja.mdx | 0 .../examples/optimistic-ui.ko.mdx | 0 .../examples/optimistic-ui.mdx | 0 .../examples/optimistic-ui.pt.mdx | 0 .../examples/optimistic-ui.ru.mdx | 0 .../examples/ssr.cn.mdx | 0 .../examples/ssr.es.mdx | 0 .../examples/ssr.fr.mdx | 0 {pages => content}/examples/ssr.ja.mdx | 0 {pages => content}/examples/ssr.ko.mdx | 0 .../ssr.pt-BR.mdx => content/examples/ssr.mdx | 0 .../ssr.ru.mdx => content/examples/ssr.pt.mdx | 0 .../examples/ssr.ru.mdx | 0 .../examples/subscription.cn.mdx | 0 .../examples/subscription.es.mdx | 0 .../examples/subscription.fr.mdx | 0 .../examples/subscription.ja.mdx | 0 .../examples/subscription.ko.mdx | 0 .../examples/subscription.mdx | 0 .../examples/subscription.pt.mdx | 0 .../examples/subscription.ru.mdx | 0 geistdocs.tsx | 78 + hooks/geistdocs/use-chat.ts | 23 + hooks/geistdocs/use-sidebar.ts | 13 + hooks/use-mobile.ts | 19 + jsconfig.json | 5 - lib/geistdocs/db.ts | 21 + lib/geistdocs/fonts.ts | 18 + lib/geistdocs/i18n.ts | 13 + lib/geistdocs/source.ts | 46 + lib/utils.ts | 6 + license.md | 190 - middleware.js | 1 - next-env.d.ts | 6 + next.config.js | 66 - next.config.ts | 81 + package.json | 86 +- pages/_app.mdx | 11 - pages/_document.js | 20 - pages/_meta.en-US.json | 22 - pages/_meta.es-ES.json | 22 - pages/_meta.fr-FR.json | 22 - pages/_meta.ja.json | 22 - pages/_meta.ko.json | 22 - pages/_meta.pt-BR.json | 22 - pages/_meta.ru.json | 22 - pages/_meta.zh-CN.json | 22 - pages/blog.en-US.mdx | 10 - pages/blog.es-ES.mdx | 10 - pages/blog.fr-FR.mdx | 10 - pages/blog.ja.mdx | 10 - pages/blog.ko.mdx | 10 - pages/blog.pt-BR.mdx | 10 - pages/blog.ru.mdx | 10 - pages/blog.zh-CN.mdx | 10 - pages/blog/_meta.en-US.json | 4 - pages/blog/_meta.es-ES.json | 4 - pages/blog/_meta.fr-FR.json | 4 - pages/blog/_meta.ja.json | 4 - pages/blog/_meta.ko.json | 4 - pages/blog/_meta.pt-BR.json | 4 - pages/blog/_meta.ru.json | 4 - pages/blog/_meta.zh-CN.json | 4 - pages/docs/_meta.en-US.json | 24 - pages/docs/_meta.es-ES.json | 24 - pages/docs/_meta.fr-FR.json | 24 - pages/docs/_meta.ja.json | 24 - pages/docs/_meta.ko.json | 24 - pages/docs/_meta.pt-BR.json | 24 - pages/docs/_meta.ru.json | 24 - pages/docs/_meta.zh-CN.json | 24 - pages/docs/advanced/_meta.en-US.json | 7 - pages/docs/advanced/_meta.es-ES.json | 7 - pages/docs/advanced/_meta.fr-FR.json | 7 - pages/docs/advanced/_meta.ja.json | 7 - pages/docs/advanced/_meta.ko.json | 8 - pages/docs/advanced/_meta.pt-BR.json | 7 - pages/docs/advanced/_meta.ru.json | 7 - pages/docs/advanced/_meta.zh-CN.json | 7 - pages/examples/_meta.en-US.json | 9 - pages/examples/_meta.es-ES.json | 8 - pages/examples/_meta.fr-FR.json | 9 - pages/examples/_meta.ja.json | 9 - pages/examples/_meta.ko.json | 9 - pages/examples/_meta.pt-BR.json | 9 - pages/examples/_meta.ru.json | 9 - pages/examples/_meta.zh-CN.json | 9 - pages/index.en-US.mdx | 84 - pages/index.es-ES.mdx | 86 - pages/index.fr-FR.mdx | 84 - pages/index.ja.mdx | 86 - pages/index.ko.mdx | 84 - pages/index.pt-BR.mdx | 83 - pages/index.ru.mdx | 85 - pages/index.zh-CN.mdx | 84 - pnpm-lock.yaml | 3819 ----------------- postcss.config.js | 6 - postcss.config.mjs | 5 + proxy.ts | 32 + source.config.ts | 56 + styles.css | 33 - tailwind.config.js | 7 - theme.config.js | 162 - translations/text.js | 136 - tsconfig.json | 37 + 475 files changed, 14763 insertions(+), 7980 deletions(-) delete mode 100644 README.md create mode 100644 app/[lang]/(home)/components/centered-section.tsx create mode 100644 app/[lang]/(home)/components/cta.tsx create mode 100644 app/[lang]/(home)/components/hero.tsx create mode 100644 app/[lang]/(home)/components/one-two-section.tsx create mode 100644 app/[lang]/(home)/components/templates.tsx create mode 100644 app/[lang]/(home)/components/text-grid-section.tsx create mode 100644 app/[lang]/(home)/copy.ts create mode 100644 app/[lang]/(home)/layout.tsx create mode 100644 app/[lang]/(home)/page.tsx create mode 100644 app/[lang]/blog/[...slug]/page.tsx create mode 100644 app/[lang]/blog/layout.tsx create mode 100644 app/[lang]/docs/[[...slug]]/page.tsx create mode 100644 app/[lang]/docs/layout.tsx create mode 100644 app/[lang]/examples/[[...slug]]/page.tsx create mode 100644 app/[lang]/examples/layout.tsx create mode 100644 app/[lang]/layout.tsx create mode 100644 app/[lang]/llms.mdx/[[...slug]]/route.ts create mode 100644 app/[lang]/llms.txt/route.ts create mode 100644 app/[lang]/og/[...slug]/background.png create mode 100644 app/[lang]/og/[...slug]/geist-sans-regular.ttf create mode 100644 app/[lang]/og/[...slug]/geist-sans-semibold.ttf create mode 100644 app/[lang]/og/[...slug]/route.tsx create mode 100644 app/[lang]/rss.xml/route.ts create mode 100644 app/actions/feedback/emotions.ts create mode 100644 app/actions/feedback/index.ts create mode 100644 app/api/chat/route.ts create mode 100644 app/api/chat/tools.ts create mode 100644 app/api/chat/types.ts create mode 100644 app/api/chat/utils.ts create mode 100644 app/api/search/route.ts create mode 100644 app/favicon.ico create mode 100644 app/global.css create mode 100644 app/styles/geistdocs.css create mode 100644 components.json create mode 100644 components/ai-elements/code-block.tsx create mode 100644 components/ai-elements/conversation.tsx create mode 100644 components/ai-elements/message.tsx create mode 100644 components/ai-elements/open-in-chat.tsx create mode 100644 components/ai-elements/prompt-input.tsx create mode 100644 components/ai-elements/shimmer.tsx create mode 100644 components/ai-elements/sources.tsx create mode 100644 components/ai-elements/suggestion.tsx delete mode 100644 components/blog-index.js rename components/{authors.js => custom/authors.tsx} (58%) create mode 100644 components/custom/bleed.tsx rename components/{diagrams/cache.js => custom/diagrams/cache.tsx} (70%) rename components/{diagrams/infinite.js => custom/diagrams/infinite.tsx} (72%) rename components/{diagrams/pagination.js => custom/diagrams/pagination.tsx} (86%) rename components/{diagrams/welcome.js => custom/diagrams/welcome.tsx} (74%) rename components/{ => custom}/excalidraw/state-machine.excalidraw (100%) rename components/{logo.js => custom/logo.tsx} (92%) delete mode 100644 components/features.js delete mode 100644 components/features.module.css create mode 100644 components/geistdocs/ask-ai.tsx create mode 100644 components/geistdocs/callout.tsx create mode 100644 components/geistdocs/chat.tsx create mode 100644 components/geistdocs/code-block-tabs.tsx create mode 100644 components/geistdocs/code-block.tsx create mode 100644 components/geistdocs/copy-chat.tsx create mode 100644 components/geistdocs/copy-page.tsx create mode 100644 components/geistdocs/desktop-menu.tsx create mode 100644 components/geistdocs/docs-layout.tsx create mode 100644 components/geistdocs/docs-page.tsx create mode 100644 components/geistdocs/edit-source.tsx create mode 100644 components/geistdocs/feedback.tsx create mode 100644 components/geistdocs/footer.tsx create mode 100644 components/geistdocs/github-button.tsx create mode 100644 components/geistdocs/home-layout.tsx create mode 100644 components/geistdocs/icons.tsx create mode 100644 components/geistdocs/installer.tsx create mode 100644 components/geistdocs/language-selector.tsx create mode 100644 components/geistdocs/mdx-components.tsx create mode 100644 components/geistdocs/mermaid.tsx create mode 100644 components/geistdocs/message-metadata.tsx create mode 100644 components/geistdocs/mobile-menu.tsx create mode 100644 components/geistdocs/navbar.tsx create mode 100644 components/geistdocs/open-in-chat.tsx create mode 100644 components/geistdocs/provider.tsx create mode 100644 components/geistdocs/rss-button.tsx create mode 100644 components/geistdocs/scroll-top.tsx create mode 100644 components/geistdocs/search.tsx create mode 100644 components/geistdocs/sidebar.tsx create mode 100644 components/geistdocs/theme-toggle.tsx create mode 100644 components/geistdocs/video.tsx delete mode 100644 components/icons/backend-agnostic.js delete mode 100644 components/icons/lightweight.js delete mode 100644 components/icons/pagination.js delete mode 100644 components/icons/realtime.js delete mode 100644 components/icons/remote-local.js delete mode 100644 components/icons/rendering-strategies.js delete mode 100644 components/icons/suspense.js delete mode 100644 components/icons/typescript.js rename translations/svgs.js => components/translations/svgs.ts (81%) create mode 100644 components/ui/accordion.tsx create mode 100644 components/ui/alert-dialog.tsx create mode 100644 components/ui/alert.tsx create mode 100644 components/ui/aspect-ratio.tsx create mode 100644 components/ui/avatar.tsx create mode 100644 components/ui/badge.tsx create mode 100644 components/ui/breadcrumb.tsx create mode 100644 components/ui/button-group.tsx create mode 100644 components/ui/button.tsx create mode 100644 components/ui/calendar.tsx create mode 100644 components/ui/card.tsx create mode 100644 components/ui/carousel.tsx create mode 100644 components/ui/chart.tsx create mode 100644 components/ui/checkbox.tsx create mode 100644 components/ui/collapsible.tsx create mode 100644 components/ui/command.tsx create mode 100644 components/ui/context-menu.tsx create mode 100644 components/ui/dialog.tsx create mode 100644 components/ui/drawer.tsx create mode 100644 components/ui/dropdown-menu.tsx create mode 100644 components/ui/empty.tsx create mode 100644 components/ui/field.tsx create mode 100644 components/ui/form.tsx create mode 100644 components/ui/hover-card.tsx create mode 100644 components/ui/input-group.tsx create mode 100644 components/ui/input-otp.tsx create mode 100644 components/ui/input.tsx create mode 100644 components/ui/item.tsx create mode 100644 components/ui/kbd.tsx create mode 100644 components/ui/label.tsx create mode 100644 components/ui/menubar.tsx create mode 100644 components/ui/navigation-menu.tsx create mode 100644 components/ui/pagination.tsx create mode 100644 components/ui/popover.tsx create mode 100644 components/ui/progress.tsx create mode 100644 components/ui/radio-group.tsx create mode 100644 components/ui/resizable.tsx create mode 100644 components/ui/scroll-area.tsx create mode 100644 components/ui/select.tsx create mode 100644 components/ui/separator.tsx create mode 100644 components/ui/sheet.tsx create mode 100644 components/ui/sidebar.tsx create mode 100644 components/ui/skeleton.tsx create mode 100644 components/ui/slider.tsx create mode 100644 components/ui/sonner.tsx create mode 100644 components/ui/spinner.tsx create mode 100644 components/ui/switch.tsx create mode 100644 components/ui/table.tsx create mode 100644 components/ui/tabs.tsx create mode 100644 components/ui/textarea.tsx create mode 100644 components/ui/toggle-group.tsx create mode 100644 components/ui/toggle.tsx create mode 100644 components/ui/tooltip.tsx delete mode 100644 components/use-locales-map.js delete mode 100644 components/vercel.js delete mode 100644 components/video.js rename pages/blog/swr-v1.zh-CN.mdx => content/blog/swr-v1.cn.mdx (96%) rename pages/blog/swr-v1.es-ES.mdx => content/blog/swr-v1.es.mdx (96%) rename pages/blog/swr-v1.fr-FR.mdx => content/blog/swr-v1.fr.mdx (96%) rename {pages => content}/blog/swr-v1.ja.mdx (97%) rename {pages => content}/blog/swr-v1.ko.mdx (96%) rename pages/blog/swr-v1.en-US.mdx => content/blog/swr-v1.mdx (96%) rename pages/blog/swr-v1.pt-BR.mdx => content/blog/swr-v1.pt.mdx (94%) rename {pages => content}/blog/swr-v1.ru.mdx (97%) rename pages/blog/swr-v2.zh-CN.mdx => content/blog/swr-v2.cn.mdx (97%) rename pages/blog/swr-v2.es-ES.mdx => content/blog/swr-v2.es.mdx (97%) rename pages/blog/swr-v2.fr-FR.mdx => content/blog/swr-v2.fr.mdx (97%) rename {pages => content}/blog/swr-v2.ja.mdx (98%) rename {pages => content}/blog/swr-v2.ko.mdx (97%) rename pages/blog/swr-v2.en-US.mdx => content/blog/swr-v2.mdx (97%) rename pages/blog/swr-v2.pt-BR.mdx => content/blog/swr-v2.pt.mdx (98%) rename {pages => content}/blog/swr-v2.ru.mdx (98%) rename pages/docs/advanced/cache.zh-CN.mdx => content/docs/advanced/cache.cn.mdx (98%) rename pages/docs/advanced/cache.en-US.mdx => content/docs/advanced/cache.es.mdx (98%) rename pages/docs/advanced/cache.fr-FR.mdx => content/docs/advanced/cache.fr.mdx (98%) rename {pages => content}/docs/advanced/cache.ja.mdx (98%) rename {pages => content}/docs/advanced/cache.ko.mdx (98%) rename pages/docs/advanced/cache.es-ES.mdx => content/docs/advanced/cache.mdx (98%) rename pages/docs/advanced/cache.pt-BR.mdx => content/docs/advanced/cache.pt.mdx (98%) rename {pages => content}/docs/advanced/cache.ru.mdx (98%) rename pages/docs/advanced/devtools.zh-CN.mdx => content/docs/advanced/devtools.cn.mdx (92%) rename pages/docs/advanced/devtools.en-US.mdx => content/docs/advanced/devtools.es.mdx (92%) rename pages/docs/advanced/devtools.fr-FR.mdx => content/docs/advanced/devtools.fr.mdx (91%) rename {pages => content}/docs/advanced/devtools.ja.mdx (92%) rename {pages => content}/docs/advanced/devtools.ko.mdx (93%) rename pages/docs/advanced/devtools.es-ES.mdx => content/docs/advanced/devtools.mdx (92%) rename pages/docs/advanced/devtools.pt-BR.mdx => content/docs/advanced/devtools.pt.mdx (92%) rename {pages => content}/docs/advanced/devtools.ru.mdx (91%) rename pages/docs/advanced/performance.zh-CN.mdx => content/docs/advanced/performance.cn.mdx (99%) rename pages/docs/advanced/performance.es-ES.mdx => content/docs/advanced/performance.es.mdx (99%) rename pages/docs/advanced/performance.fr-FR.mdx => content/docs/advanced/performance.fr.mdx (99%) rename {pages => content}/docs/advanced/performance.ja.mdx (99%) rename {pages => content}/docs/advanced/performance.ko.mdx (99%) rename pages/docs/advanced/performance.en-US.mdx => content/docs/advanced/performance.mdx (99%) rename pages/docs/advanced/performance.pt-BR.mdx => content/docs/advanced/performance.pt.mdx (99%) rename {pages => content}/docs/advanced/performance.ru.mdx (99%) rename pages/docs/advanced/react-native.zh-CN.mdx => content/docs/advanced/react-native.cn.mdx (97%) rename pages/docs/advanced/react-native.es-ES.mdx => content/docs/advanced/react-native.es.mdx (98%) rename pages/docs/advanced/react-native.fr-FR.mdx => content/docs/advanced/react-native.fr.mdx (98%) rename {pages => content}/docs/advanced/react-native.ja.mdx (98%) rename {pages => content}/docs/advanced/react-native.ko.mdx (98%) rename pages/docs/advanced/react-native.en-US.mdx => content/docs/advanced/react-native.mdx (97%) rename pages/docs/advanced/react-native.pt-BR.mdx => content/docs/advanced/react-native.pt.mdx (95%) rename {pages => content}/docs/advanced/react-native.ru.mdx (98%) rename pages/docs/advanced/understanding.zh-CN.mdx => content/docs/advanced/understanding.cn.mdx (98%) rename pages/docs/advanced/understanding.en-US.mdx => content/docs/advanced/understanding.es.mdx (97%) rename pages/docs/advanced/understanding.fr-FR.mdx => content/docs/advanced/understanding.fr.mdx (98%) rename {pages => content}/docs/advanced/understanding.ja.mdx (98%) rename {pages => content}/docs/advanced/understanding.ko.mdx (98%) rename pages/docs/advanced/understanding.es-ES.mdx => content/docs/advanced/understanding.mdx (97%) rename pages/docs/advanced/understanding.pt-BR.mdx => content/docs/advanced/understanding.pt.mdx (98%) rename {pages => content}/docs/advanced/understanding.ru.mdx (98%) rename pages/docs/api.zh-CN.mdx => content/docs/api.cn.mdx (98%) rename pages/docs/api.es-ES.mdx => content/docs/api.es.mdx (98%) rename pages/docs/api.fr-FR.mdx => content/docs/api.fr.mdx (98%) rename {pages => content}/docs/api.ja.mdx (99%) rename {pages => content}/docs/api.ko.mdx (98%) rename pages/docs/api.en-US.mdx => content/docs/api.mdx (98%) rename pages/docs/api.pt-BR.mdx => content/docs/api.pt.mdx (98%) rename {pages => content}/docs/api.ru.mdx (99%) rename pages/docs/arguments.zh-CN.mdx => content/docs/arguments.cn.mdx (97%) rename pages/docs/arguments.es-ES.mdx => content/docs/arguments.es.mdx (97%) rename pages/docs/arguments.fr-FR.mdx => content/docs/arguments.fr.mdx (97%) rename {pages => content}/docs/arguments.ja.mdx (97%) rename {pages => content}/docs/arguments.ko.mdx (97%) rename pages/docs/arguments.en-US.mdx => content/docs/arguments.mdx (97%) rename pages/docs/arguments.pt-BR.mdx => content/docs/arguments.pt.mdx (97%) rename {pages => content}/docs/arguments.ru.mdx (98%) rename pages/docs/conditional-fetching.zh-CN.mdx => content/docs/conditional-fetching.cn.mdx (97%) rename pages/docs/conditional-fetching.es-ES.mdx => content/docs/conditional-fetching.es.mdx (97%) rename pages/docs/conditional-fetching.fr-FR.mdx => content/docs/conditional-fetching.fr.mdx (96%) rename {pages => content}/docs/conditional-fetching.ja.mdx (97%) rename {pages => content}/docs/conditional-fetching.ko.mdx (97%) rename pages/docs/conditional-fetching.en-US.mdx => content/docs/conditional-fetching.mdx (97%) rename pages/docs/conditional-fetching.pt-BR.mdx => content/docs/conditional-fetching.pt.mdx (95%) rename {pages => content}/docs/conditional-fetching.ru.mdx (97%) rename pages/docs/data-fetching.zh-CN.mdx => content/docs/data-fetching.cn.mdx (95%) rename pages/docs/data-fetching.es-ES.mdx => content/docs/data-fetching.es.mdx (95%) rename pages/docs/data-fetching.fr-FR.mdx => content/docs/data-fetching.fr.mdx (95%) rename {pages => content}/docs/data-fetching.ja.mdx (95%) rename {pages => content}/docs/data-fetching.ko.mdx (95%) rename pages/docs/data-fetching.en-US.mdx => content/docs/data-fetching.mdx (95%) rename pages/docs/data-fetching.pt-BR.mdx => content/docs/data-fetching.pt.mdx (92%) rename {pages => content}/docs/data-fetching.ru.mdx (96%) rename pages/docs/error-handling.zh-CN.mdx => content/docs/error-handling.cn.mdx (97%) rename pages/docs/error-handling.es-ES.mdx => content/docs/error-handling.es.mdx (97%) rename pages/docs/error-handling.fr-FR.mdx => content/docs/error-handling.fr.mdx (97%) rename {pages => content}/docs/error-handling.ja.mdx (97%) rename {pages => content}/docs/error-handling.ko.mdx (97%) rename pages/docs/error-handling.en-US.mdx => content/docs/error-handling.mdx (97%) rename pages/docs/error-handling.pt-BR.mdx => content/docs/error-handling.pt.mdx (97%) rename {pages => content}/docs/error-handling.ru.mdx (97%) rename pages/docs/getting-started.zh-CN.mdx => content/docs/getting-started.cn.mdx (93%) rename pages/docs/getting-started.es-ES.mdx => content/docs/getting-started.es.mdx (93%) rename pages/docs/getting-started.fr-FR.mdx => content/docs/getting-started.fr.mdx (93%) rename {pages => content}/docs/getting-started.ja.mdx (94%) rename {pages => content}/docs/getting-started.ko.mdx (94%) rename pages/docs/getting-started.en-US.mdx => content/docs/getting-started.mdx (93%) rename pages/docs/getting-started.pt-BR.mdx => content/docs/getting-started.pt.mdx (93%) rename {pages => content}/docs/getting-started.ru.mdx (95%) rename pages/docs/global-configuration.zh-CN.mdx => content/docs/global-configuration.cn.mdx (99%) rename pages/docs/global-configuration.es-ES.mdx => content/docs/global-configuration.es.mdx (98%) rename pages/docs/global-configuration.fr-FR.mdx => content/docs/global-configuration.fr.mdx (98%) rename {pages => content}/docs/global-configuration.ja.mdx (98%) rename {pages => content}/docs/global-configuration.ko.mdx (99%) rename pages/docs/global-configuration.en-US.mdx => content/docs/global-configuration.mdx (98%) rename pages/docs/global-configuration.pt-BR.mdx => content/docs/global-configuration.pt.mdx (98%) rename {pages => content}/docs/global-configuration.ru.mdx (98%) create mode 100644 content/docs/meta.json rename pages/docs/middleware.zh-CN.mdx => content/docs/middleware.cn.mdx (98%) rename pages/docs/middleware.en-US.mdx => content/docs/middleware.es.mdx (99%) rename pages/docs/middleware.fr-FR.mdx => content/docs/middleware.fr.mdx (99%) rename {pages => content}/docs/middleware.ja.mdx (99%) rename {pages => content}/docs/middleware.ko.mdx (99%) rename pages/docs/middleware.es-ES.mdx => content/docs/middleware.mdx (99%) rename pages/docs/middleware.pt-BR.mdx => content/docs/middleware.pt.mdx (95%) rename {pages => content}/docs/middleware.ru.mdx (98%) rename pages/docs/mutation.zh-CN.mdx => content/docs/mutation.cn.mdx (99%) rename pages/docs/mutation.es-ES.mdx => content/docs/mutation.es.mdx (99%) rename pages/docs/mutation.fr-FR.mdx => content/docs/mutation.fr.mdx (99%) rename {pages => content}/docs/mutation.ja.mdx (99%) rename {pages => content}/docs/mutation.ko.mdx (99%) rename pages/docs/mutation.en-US.mdx => content/docs/mutation.mdx (99%) rename pages/docs/mutation.pt-BR.mdx => content/docs/mutation.pt.mdx (99%) rename {pages => content}/docs/mutation.ru.mdx (99%) rename pages/docs/pagination.zh-CN.mdx => content/docs/pagination.cn.mdx (98%) rename pages/docs/pagination.es-ES.mdx => content/docs/pagination.es.mdx (98%) rename pages/docs/pagination.fr-FR.mdx => content/docs/pagination.fr.mdx (98%) rename {pages => content}/docs/pagination.ja.mdx (98%) rename {pages => content}/docs/pagination.ko.mdx (98%) rename pages/docs/pagination.en-US.mdx => content/docs/pagination.mdx (98%) rename pages/docs/pagination.pt-BR.mdx => content/docs/pagination.pt.mdx (98%) rename {pages => content}/docs/pagination.ru.mdx (98%) rename pages/docs/prefetching.zh-CN.mdx => content/docs/prefetching.cn.mdx (99%) rename pages/docs/prefetching.es-ES.mdx => content/docs/prefetching.es.mdx (99%) rename pages/docs/prefetching.fr-FR.mdx => content/docs/prefetching.fr.mdx (98%) rename {pages => content}/docs/prefetching.ja.mdx (98%) rename {pages => content}/docs/prefetching.ko.mdx (98%) rename pages/docs/prefetching.en-US.mdx => content/docs/prefetching.mdx (99%) rename pages/docs/prefetching.pt-BR.mdx => content/docs/prefetching.pt.mdx (99%) rename {pages => content}/docs/prefetching.ru.mdx (98%) rename pages/docs/revalidation.zh-CN.mdx => content/docs/revalidation.cn.mdx (95%) rename pages/docs/revalidation.es-ES.mdx => content/docs/revalidation.es.mdx (95%) rename pages/docs/revalidation.fr-FR.mdx => content/docs/revalidation.fr.mdx (95%) rename {pages => content}/docs/revalidation.ja.mdx (96%) rename {pages => content}/docs/revalidation.ko.mdx (96%) rename pages/docs/revalidation.en-US.mdx => content/docs/revalidation.mdx (95%) rename pages/docs/revalidation.pt-BR.mdx => content/docs/revalidation.pt.mdx (95%) rename {pages => content}/docs/revalidation.ru.mdx (96%) rename pages/docs/subscription.zh-CN.mdx => content/docs/subscription.cn.mdx (98%) rename pages/docs/subscription.es-ES.mdx => content/docs/subscription.es.mdx (98%) rename pages/docs/subscription.fr-FR.mdx => content/docs/subscription.fr.mdx (98%) rename {pages => content}/docs/subscription.ja.mdx (98%) rename {pages => content}/docs/subscription.ko.mdx (98%) rename pages/docs/subscription.en-US.mdx => content/docs/subscription.mdx (98%) rename pages/docs/subscription.pt-BR.mdx => content/docs/subscription.pt.mdx (98%) rename {pages => content}/docs/subscription.ru.mdx (98%) rename pages/docs/suspense.zh-CN.mdx => content/docs/suspense.cn.mdx (97%) rename pages/docs/suspense.es-ES.mdx => content/docs/suspense.es.mdx (97%) rename pages/docs/suspense.fr-FR.mdx => content/docs/suspense.fr.mdx (98%) rename {pages => content}/docs/suspense.ja.mdx (98%) rename {pages => content}/docs/suspense.ko.mdx (97%) rename pages/docs/suspense.en-US.mdx => content/docs/suspense.mdx (97%) rename pages/docs/suspense.pt-BR.mdx => content/docs/suspense.pt.mdx (97%) rename {pages => content}/docs/suspense.ru.mdx (98%) rename pages/docs/typescript.zh-CN.mdx => content/docs/typescript.cn.mdx (99%) rename pages/docs/typescript.es-ES.mdx => content/docs/typescript.es.mdx (99%) rename pages/docs/typescript.fr-FR.mdx => content/docs/typescript.fr.mdx (99%) rename {pages => content}/docs/typescript.ja.mdx (99%) rename {pages => content}/docs/typescript.ko.mdx (99%) rename pages/docs/typescript.en-US.mdx => content/docs/typescript.mdx (99%) rename pages/docs/typescript.pt-BR.mdx => content/docs/typescript.pt.mdx (99%) rename {pages => content}/docs/typescript.ru.mdx (99%) rename pages/docs/with-nextjs.zh-CN.mdx => content/docs/with-nextjs.cn.mdx (98%) rename pages/docs/with-nextjs.fr-FR.mdx => content/docs/with-nextjs.es.mdx (98%) rename pages/docs/with-nextjs.es-ES.mdx => content/docs/with-nextjs.fr.mdx (98%) rename {pages => content}/docs/with-nextjs.ja.mdx (98%) rename {pages => content}/docs/with-nextjs.ko.mdx (98%) rename pages/docs/with-nextjs.en-US.mdx => content/docs/with-nextjs.mdx (98%) rename pages/docs/with-nextjs.pt-BR.mdx => content/docs/with-nextjs.pt.mdx (96%) rename {pages => content}/docs/with-nextjs.ru.mdx (98%) rename pages/examples/auth.zh-CN.mdx => content/examples/auth.cn.mdx (100%) rename pages/examples/auth.es-ES.mdx => content/examples/auth.es.mdx (100%) rename pages/examples/auth.fr-FR.mdx => content/examples/auth.fr.mdx (100%) rename {pages => content}/examples/auth.ja.mdx (100%) rename {pages => content}/examples/auth.ko.mdx (100%) rename pages/examples/auth.en-US.mdx => content/examples/auth.mdx (100%) rename pages/examples/auth.pt-BR.mdx => content/examples/auth.pt.mdx (100%) rename {pages => content}/examples/auth.ru.mdx (100%) rename pages/examples/basic.zh-CN.mdx => content/examples/basic.cn.mdx (100%) rename pages/examples/basic.es-ES.mdx => content/examples/basic.es.mdx (100%) rename pages/examples/basic.fr-FR.mdx => content/examples/basic.fr.mdx (100%) rename {pages => content}/examples/basic.ja.mdx (100%) rename {pages => content}/examples/basic.ko.mdx (100%) rename pages/examples/basic.en-US.mdx => content/examples/basic.mdx (100%) rename pages/examples/basic.pt-BR.mdx => content/examples/basic.pt.mdx (100%) rename {pages => content}/examples/basic.ru.mdx (100%) rename pages/examples/error-handling.zh-CN.mdx => content/examples/error-handling.cn.mdx (100%) rename pages/examples/error-handling.es-ES.mdx => content/examples/error-handling.es.mdx (100%) rename pages/examples/error-handling.fr-FR.mdx => content/examples/error-handling.fr.mdx (100%) rename {pages => content}/examples/error-handling.ja.mdx (100%) rename {pages => content}/examples/error-handling.ko.mdx (100%) rename pages/examples/error-handling.en-US.mdx => content/examples/error-handling.mdx (100%) rename pages/examples/error-handling.pt-BR.mdx => content/examples/error-handling.pt.mdx (100%) rename {pages => content}/examples/error-handling.ru.mdx (100%) rename pages/examples/infinite-loading.zh-CN.mdx => content/examples/infinite-loading.cn.mdx (100%) rename pages/examples/infinite-loading.es-ES.mdx => content/examples/infinite-loading.es.mdx (100%) rename pages/examples/infinite-loading.fr-FR.mdx => content/examples/infinite-loading.fr.mdx (100%) rename {pages => content}/examples/infinite-loading.ja.mdx (100%) rename {pages => content}/examples/infinite-loading.ko.mdx (100%) rename pages/examples/infinite-loading.en-US.mdx => content/examples/infinite-loading.mdx (100%) rename pages/examples/infinite-loading.pt-BR.mdx => content/examples/infinite-loading.pt.mdx (100%) rename {pages => content}/examples/infinite-loading.ru.mdx (100%) rename pages/examples/optimistic-ui.en-US.mdx => content/examples/optimistic-ui.cn.mdx (100%) rename pages/examples/optimistic-ui.es-ES.mdx => content/examples/optimistic-ui.es.mdx (100%) rename pages/examples/optimistic-ui.fr-FR.mdx => content/examples/optimistic-ui.fr.mdx (100%) rename {pages => content}/examples/optimistic-ui.ja.mdx (100%) rename {pages => content}/examples/optimistic-ui.ko.mdx (100%) rename pages/examples/optimistic-ui.zh-CN.mdx => content/examples/optimistic-ui.mdx (100%) rename pages/examples/optimistic-ui.pt-BR.mdx => content/examples/optimistic-ui.pt.mdx (100%) rename {pages => content}/examples/optimistic-ui.ru.mdx (100%) rename pages/examples/ssr.en-US.mdx => content/examples/ssr.cn.mdx (100%) rename pages/examples/ssr.es-ES.mdx => content/examples/ssr.es.mdx (100%) rename pages/examples/ssr.fr-FR.mdx => content/examples/ssr.fr.mdx (100%) rename {pages => content}/examples/ssr.ja.mdx (100%) rename {pages => content}/examples/ssr.ko.mdx (100%) rename pages/examples/ssr.pt-BR.mdx => content/examples/ssr.mdx (100%) rename pages/examples/ssr.ru.mdx => content/examples/ssr.pt.mdx (100%) rename pages/examples/ssr.zh-CN.mdx => content/examples/ssr.ru.mdx (100%) rename pages/examples/subscription.en-US.mdx => content/examples/subscription.cn.mdx (100%) rename pages/examples/subscription.es-ES.mdx => content/examples/subscription.es.mdx (100%) rename pages/examples/subscription.fr-FR.mdx => content/examples/subscription.fr.mdx (100%) rename {pages => content}/examples/subscription.ja.mdx (100%) rename {pages => content}/examples/subscription.ko.mdx (100%) rename pages/examples/subscription.pt-BR.mdx => content/examples/subscription.mdx (100%) rename pages/examples/subscription.ru.mdx => content/examples/subscription.pt.mdx (100%) rename pages/examples/subscription.zh-CN.mdx => content/examples/subscription.ru.mdx (100%) create mode 100644 geistdocs.tsx create mode 100644 hooks/geistdocs/use-chat.ts create mode 100644 hooks/geistdocs/use-sidebar.ts create mode 100644 hooks/use-mobile.ts delete mode 100644 jsconfig.json create mode 100644 lib/geistdocs/db.ts create mode 100644 lib/geistdocs/fonts.ts create mode 100644 lib/geistdocs/i18n.ts create mode 100644 lib/geistdocs/source.ts create mode 100644 lib/utils.ts delete mode 100644 license.md delete mode 100644 middleware.js create mode 100644 next-env.d.ts delete mode 100644 next.config.js create mode 100644 next.config.ts delete mode 100644 pages/_app.mdx delete mode 100644 pages/_document.js delete mode 100644 pages/_meta.en-US.json delete mode 100644 pages/_meta.es-ES.json delete mode 100644 pages/_meta.fr-FR.json delete mode 100644 pages/_meta.ja.json delete mode 100644 pages/_meta.ko.json delete mode 100644 pages/_meta.pt-BR.json delete mode 100644 pages/_meta.ru.json delete mode 100644 pages/_meta.zh-CN.json delete mode 100644 pages/blog.en-US.mdx delete mode 100644 pages/blog.es-ES.mdx delete mode 100644 pages/blog.fr-FR.mdx delete mode 100644 pages/blog.ja.mdx delete mode 100644 pages/blog.ko.mdx delete mode 100644 pages/blog.pt-BR.mdx delete mode 100644 pages/blog.ru.mdx delete mode 100644 pages/blog.zh-CN.mdx delete mode 100644 pages/blog/_meta.en-US.json delete mode 100644 pages/blog/_meta.es-ES.json delete mode 100644 pages/blog/_meta.fr-FR.json delete mode 100644 pages/blog/_meta.ja.json delete mode 100644 pages/blog/_meta.ko.json delete mode 100644 pages/blog/_meta.pt-BR.json delete mode 100644 pages/blog/_meta.ru.json delete mode 100644 pages/blog/_meta.zh-CN.json delete mode 100644 pages/docs/_meta.en-US.json delete mode 100644 pages/docs/_meta.es-ES.json delete mode 100644 pages/docs/_meta.fr-FR.json delete mode 100644 pages/docs/_meta.ja.json delete mode 100644 pages/docs/_meta.ko.json delete mode 100644 pages/docs/_meta.pt-BR.json delete mode 100644 pages/docs/_meta.ru.json delete mode 100644 pages/docs/_meta.zh-CN.json delete mode 100644 pages/docs/advanced/_meta.en-US.json delete mode 100644 pages/docs/advanced/_meta.es-ES.json delete mode 100644 pages/docs/advanced/_meta.fr-FR.json delete mode 100644 pages/docs/advanced/_meta.ja.json delete mode 100644 pages/docs/advanced/_meta.ko.json delete mode 100644 pages/docs/advanced/_meta.pt-BR.json delete mode 100644 pages/docs/advanced/_meta.ru.json delete mode 100644 pages/docs/advanced/_meta.zh-CN.json delete mode 100644 pages/examples/_meta.en-US.json delete mode 100644 pages/examples/_meta.es-ES.json delete mode 100644 pages/examples/_meta.fr-FR.json delete mode 100644 pages/examples/_meta.ja.json delete mode 100644 pages/examples/_meta.ko.json delete mode 100644 pages/examples/_meta.pt-BR.json delete mode 100644 pages/examples/_meta.ru.json delete mode 100644 pages/examples/_meta.zh-CN.json delete mode 100644 pages/index.en-US.mdx delete mode 100644 pages/index.es-ES.mdx delete mode 100644 pages/index.fr-FR.mdx delete mode 100644 pages/index.ja.mdx delete mode 100644 pages/index.ko.mdx delete mode 100644 pages/index.pt-BR.mdx delete mode 100644 pages/index.ru.mdx delete mode 100644 pages/index.zh-CN.mdx delete mode 100644 pnpm-lock.yaml delete mode 100644 postcss.config.js create mode 100644 postcss.config.mjs create mode 100644 proxy.ts create mode 100644 source.config.ts delete mode 100644 styles.css delete mode 100644 tailwind.config.js delete mode 100644 theme.config.js delete mode 100644 translations/text.js create mode 100644 tsconfig.json diff --git a/README.md b/README.md deleted file mode 100644 index 00640d65..00000000 --- a/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# [SWR website](https://swr.vercel.app) - -The official website for [SWR](https://github.com/vercel/swr). - -The project uses [pnpm](https://pnpm.io), [Nextra](https://nextra.vercel.app) and deploys via [Vercel](https://vercel.com). To develop it locally, clone this repository and run the following command to start the local dev server: - -```bash -pnpm install -pnpm dev -``` - -And visit `localhost:3000` to preview your changes. - -## Contributing - -When making a change, or creating a new page, please make sure to edit all language files. You can simply copy the content of the edited English document (or the edited paragraph) and apply it to other language files. And then, volunteers are welcome to help with any untranslated sections. - -## Contributors - -- [https://github.com/vercel/swr-site/graphs/contributors](https://github.com/vercel/swr-site/graphs/contributors) -- Simplified Chinese translation done by Fang Lu ([@huzhengen](https://github.com/huzhengen)) -- Spanish translation done by Markoz Peña ([@markozxuu](https://twitter.com/markozxuu)) -- Japanese translation done by uttk ([@uttk](https://github.com/uttk)), Tomohiro SHIOYA ([@shioyang](https://github.com/shioyang)) -- Korean translation done by SeulGi Choi ([@cs09g](https://github.com/cs09g)) -- Russian translation done by Valentin Politov ([@valentinpolitov](https://github.com/valentinpolitov)) -- Brazilian Portuguese translation done by Guilherme Sousa ([@guilherssousa](https://github.com/guilherssousa)) -- French translation done by [@Olafr9500](https://github.com/Olafr9500) diff --git a/app/[lang]/(home)/components/centered-section.tsx b/app/[lang]/(home)/components/centered-section.tsx new file mode 100644 index 00000000..859fa2ca --- /dev/null +++ b/app/[lang]/(home)/components/centered-section.tsx @@ -0,0 +1,26 @@ +import type { ReactNode } from 'react' + +type CenteredSectionProps = { + title: string + description: string + children?: ReactNode +} + +export const CenteredSection = ({ + title, + description, + children +}: CenteredSectionProps) => ( +
+
+

+ {title} +

+

+ {description} +

+
+ + {children} +
+) diff --git a/app/[lang]/(home)/components/cta.tsx b/app/[lang]/(home)/components/cta.tsx new file mode 100644 index 00000000..cf25a9b5 --- /dev/null +++ b/app/[lang]/(home)/components/cta.tsx @@ -0,0 +1,19 @@ +import DynamicLink from "fumadocs-core/dynamic-link"; +import { Button } from "@/components/ui/button"; + +type CTAProps = { + title: string; + href: string; + cta: string; +}; + +export const CTA = ({ title, href, cta }: CTAProps) => ( +
+

+ {title} +

+ +
+); diff --git a/app/[lang]/(home)/components/hero.tsx b/app/[lang]/(home)/components/hero.tsx new file mode 100644 index 00000000..b97397f9 --- /dev/null +++ b/app/[lang]/(home)/components/hero.tsx @@ -0,0 +1,29 @@ +import type { ReactNode } from 'react' +import { Badge } from '@/components/ui/badge' + +type HeroProps = { + badge?: string + title: string + description: string + children: ReactNode +} + +export const Hero = ({ badge, title, description, children }: HeroProps) => ( +
+
+ {badge && ( + +
+

{badge}

+ + )} +

+ {title} +

+

+ {description} +

+
+ {children} +
+) diff --git a/app/[lang]/(home)/components/one-two-section.tsx b/app/[lang]/(home)/components/one-two-section.tsx new file mode 100644 index 00000000..3c6344b4 --- /dev/null +++ b/app/[lang]/(home)/components/one-two-section.tsx @@ -0,0 +1,25 @@ +import type { ReactNode } from "react"; + +type OneTwoSectionProps = { + title: string; + description: string; + children?: ReactNode; +}; + +export const OneTwoSection = ({ + title, + description, + children, +}: OneTwoSectionProps) => ( +
+
+

+ {title} +

+

+ {description} +

+
+
{children}
+
+); diff --git a/app/[lang]/(home)/components/templates.tsx b/app/[lang]/(home)/components/templates.tsx new file mode 100644 index 00000000..0be9027a --- /dev/null +++ b/app/[lang]/(home)/components/templates.tsx @@ -0,0 +1,50 @@ +import Image from "next/image"; +import { cn } from "@/lib/utils"; + +type TemplatesProps = { + title: string; + description: string; + data: { + title: string; + description: string; + link: string; + image: string; + }[]; +}; + +export const Templates = ({ title, description, data }: TemplatesProps) => ( +
+
+

+ {title} +

+

+ {description} +

+
+
+ {data.map((item) => ( + +

{item.title}

+

+ {item.description} +

+ {item.title} +
+ ))} +
+
+); diff --git a/app/[lang]/(home)/components/text-grid-section.tsx b/app/[lang]/(home)/components/text-grid-section.tsx new file mode 100644 index 00000000..89a05eae --- /dev/null +++ b/app/[lang]/(home)/components/text-grid-section.tsx @@ -0,0 +1,20 @@ +type TextGridSectionProps = { + data: { + id: string; + title: string; + description: string; + }[]; +}; + +export const TextGridSection = ({ data }: TextGridSectionProps) => ( +
+ {data.map((item) => ( +
+

+ {item.title} +

+

{item.description}

+
+ ))} +
+); diff --git a/app/[lang]/(home)/copy.ts b/app/[lang]/(home)/copy.ts new file mode 100644 index 00000000..aa7c657f --- /dev/null +++ b/app/[lang]/(home)/copy.ts @@ -0,0 +1,468 @@ +import type { translations } from '@/geistdocs' + +type Locale = keyof typeof translations + +export const metadata: Record< + Locale, + { + title: string + description: string + } +> = { + en: { + title: 'SWR', + description: 'React Hooks for Data Fetching.' + }, + fr: { + title: 'SWR', + description: 'React Hooks pour la récupération de données.' + }, + ja: { + title: 'SWR', + description: 'データフェッチングのための React Hooks。' + }, + ko: { + title: 'SWR', + description: '데이터 페칭을 위한 React Hooks.' + }, + pt: { + title: 'SWR', + description: 'React Hooks para busca de dados.' + }, + ru: { + title: 'SWR', + description: 'React Hooks для получения данных.' + }, + cn: { + title: 'SWR', + description: '用于数据请求的 React Hooks。' + } +} + +export const hero: Record< + Locale, + { + title: string + description: string + } +> = { + en: { + title: 'Modern data fetching, built for React', + description: + 'SWR is a minimal API with built-in caching, revalidation, and request deduplication. It keeps your UI fast, consistent, and always up to date — with a single React hook.' + }, + fr: { + title: 'Récupération de données moderne, conçue pour React', + description: + 'SWR est une API minimale avec mise en cache intégrée, revalidation et déduplication des requêtes. Il garde votre interface rapide, cohérente et toujours à jour — avec un seul hook React.' + }, + ja: { + title: 'モダンなデータフェッチング、React 向けに構築', + description: + 'SWR は、組み込みキャッシュ、再検証、リクエストの重複排除を備えた最小限の API です。単一の React フックで、UI を高速で一貫性があり、常に最新の状態に保ちます。' + }, + ko: { + title: 'React를 위해 구축된 현대적인 데이터 페칭', + description: + 'SWR은 내장 캐싱, 재검증 및 요청 중복 제거를 갖춘 최소한의 API입니다. 단일 React 훅으로 UI를 빠르고 일관되며 항상 최신 상태로 유지합니다.' + }, + pt: { + title: 'Busca de dados moderna, construída para React', + description: + 'SWR é uma API mínima com cache integrado, revalidação e deduplicação de requisições. Mantém sua UI rápida, consistente e sempre atualizada — com um único hook React.' + }, + ru: { + title: 'Современная загрузка данных, созданная для React', + description: + 'SWR — это минималистичный API со встроенным кэшированием, ревалидацией и дедупликацией запросов. Он поддерживает ваш UI быстрым, согласованным и всегда актуальным — с помощью одного React хука.' + }, + cn: { + title: '现代化的数据请求,专为 React 打造', + description: + 'SWR 是一个极简的 API,内置缓存、重新验证和请求去重功能。只需一个 React Hook,即可让您的 UI 保持快速、一致且始终最新。' + } +} + +export const buttons: Record< + Locale, + { + getStarted: string + } +> = { + en: { + getStarted: 'Get Started' + }, + fr: { + getStarted: 'Commencer' + }, + ja: { + getStarted: '始める' + }, + ko: { + getStarted: '시작하기' + }, + pt: { + getStarted: 'Começar' + }, + ru: { + getStarted: 'Начать' + }, + cn: { + getStarted: '开始使用' + } +} + +export const oneTwoSection: Record< + Locale, + { + title: string + description: string + } +> = { + en: { + title: 'Fetch data with one hook', + description: + 'Pass a key and a fetcher to useSWR. The hook manages the request, caches the response, and keeps data fresh. You get data, error, and isLoading to drive your UI.' + }, + fr: { + title: 'Récupérer des données avec un seul hook', + description: + 'Passez une clé et un fetcher à useSWR. Le hook gère la requête, met en cache la réponse et garde les données à jour. Vous obtenez data, error et isLoading pour piloter votre interface.' + }, + ja: { + title: '1つのフックでデータを取得', + description: + 'キーとフェッチャーを useSWR に渡します。フックはリクエストを管理し、レスポンスをキャッシュし、データを最新の状態に保ちます。UI を駆動するために data、error、isLoading を取得できます。' + }, + ko: { + title: '하나의 훅으로 데이터 가져오기', + description: + '키와 fetcher를 useSWR에 전달하세요. 훅은 요청을 관리하고, 응답을 캐시하며, 데이터를 최신 상태로 유지합니다. UI를 구동하기 위해 data, error, isLoading을 얻을 수 있습니다.' + }, + pt: { + title: 'Buscar dados com um hook', + description: + 'Passe uma chave e um fetcher para useSWR. O hook gerencia a requisição, armazena a resposta em cache e mantém os dados atualizados. Você obtém data, error e isLoading para controlar sua UI.' + }, + ru: { + title: 'Загрузка данных одним хуком', + description: + 'Передайте ключ и fetcher в useSWR. Хук управляет запросом, кэширует ответ и поддерживает данные актуальными. Вы получаете data, error и isLoading для управления вашим UI.' + }, + cn: { + title: '用一个 Hook 获取数据', + description: + '向 useSWR 传递一个 key 和 fetcher。该 Hook 会管理请求、缓存响应并保持数据新鲜。您会获得 data、error 和 isLoading 来驱动您的 UI。' + } +} + +export const centeredSection: Record< + Locale, + { + title: string + description: string + } +> = { + en: { + title: 'Fetch, request and revalidate', + description: + 'SWR has you covered in all aspects of speed, correctness, and stability to help you build better experiences.' + }, + fr: { + title: 'Récupérer, demander et revalider', + description: + 'SWR vous couvre dans tous les aspects de la vitesse, de la justesse et de la stabilité pour vous aider à créer de meilleures expériences.' + }, + ja: { + title: '取得、リクエスト、そして再検証', + description: + 'SWR はスピード、正確性、安定性のあらゆる側面であなたをサポートし、より良い体験作りを助けます。' + }, + ko: { + title: '가져오기, 요청 및 재검증', + description: + 'SWR은 속도, 정확성 및 안정성의 모든 측면을 다루어 더 나은 경험을 구축하는 데 도움이 됩니다.' + }, + pt: { + title: 'Buscar, solicitar e revalidar', + description: + 'SWR cobre todos os aspectos de velocidade, correção e estabilidade para ajudá-lo a criar melhores experiências.' + }, + ru: { + title: 'Загрузка, запрос и ревалидация', + description: + 'SWR покрывает все аспекты скорости, корректности и стабильности, чтобы помочь вам создавать лучший опыт.' + }, + cn: { + title: '获取、请求和重新验证', + description: + 'SWR 在速度、正确性和稳定性等各个方面为您提供支持,帮助您构建更好的体验。' + } +} + +export const features: Record = { + en: [ + 'Fast page navigation', + 'Polling on interval', + 'Data dependency', + 'Revalidation on focus', + 'Revalidation on network recovery', + 'Local mutation (Optimistic UI)', + 'Smart error retry', + 'Pagination and scroll position recovery', + 'React Suspense' + ], + fr: [ + 'Navigation rapide entre les pages', + 'Interrogation à intervalles', + 'Dépendance des données', + 'Revalidation au focus', + 'Revalidation à la récupération du réseau', + 'Mutation locale (UI optimiste)', + "Nouvelle tentative d'erreur intelligente", + 'Pagination et récupération de la position de défilement', + 'React Suspense' + ], + ja: [ + '高速なページナビゲーション', + '間隔でのポーリング', + 'データ依存性', + 'フォーカス時の再検証', + 'ネットワーク回復時の再検証', + 'ローカルミューテーション(楽観的UI)', + 'スマートエラーリトライ', + 'ページネーションとスクロール位置の回復', + 'React Suspense' + ], + ko: [ + '빠른 페이지 탐색', + '간격별 폴링', + '데이터 종속성', + '포커스 시 재검증', + '네트워크 복구 시 재검증', + '로컬 뮤테이션(낙관적 UI)', + '스마트 오류 재시도', + '페이지네이션 및 스크롤 위치 복구', + 'React Suspense' + ], + pt: [ + 'Navegação rápida entre páginas', + 'Polling em intervalos', + 'Dependência de dados', + 'Revalidação ao focar', + 'Revalidação na recuperação da rede', + 'Mutação local (UI otimista)', + 'Nova tentativa de erro inteligente', + 'Paginação e recuperação de posição de rolagem', + 'React Suspense' + ], + ru: [ + 'Быстрая навигация по страницам', + 'Опрос с интервалами', + 'Зависимость данных', + 'Ревалидация при фокусе', + 'Ревалидация при восстановлении сети', + 'Локальная мутация (Оптимистичный UI)', + 'Умная повторная попытка при ошибке', + 'Пагинация и восстановление позиции прокрутки', + 'React Suspense' + ], + cn: [ + '快速页面导航', + '定时轮询', + '数据依赖', + '聚焦时重新验证', + '网络恢复时重新验证', + '本地变更(乐观 UI)', + '智能错误重试', + '分页和滚动位置恢复', + 'React Suspense' + ] +} + +export const textGridSection: Record< + Locale, + Array<{ + id: string + title: string + description: string + }> +> = { + en: [ + { + id: '1', + title: 'Lightweight and agnostic', + description: + 'A small API surface with support for any data source — REST, GraphQL, or custom fetchers.' + }, + { + id: '2', + title: 'Realtime and resilient', + description: + 'Automatic background revalidation, focus/reconnect updates, and utilities for pagination and streaming.' + }, + { + id: '3', + title: 'Native React ergonomics', + description: + 'Built for Suspense, compatible with SSR and SSG, and fully typed from the ground up.' + } + ], + fr: [ + { + id: '1', + title: 'Léger et agnostique', + description: + "Une petite surface d'API avec support pour n'importe quelle source de données — REST, GraphQL ou fetchers personnalisés." + }, + { + id: '2', + title: 'Temps réel et résilient', + description: + 'Revalidation automatique en arrière-plan, mises à jour focus/reconnexion et utilitaires pour la pagination et le streaming.' + }, + { + id: '3', + title: 'Ergonomie React native', + description: + 'Conçu pour Suspense, compatible avec SSR et SSG, et entièrement typé dès le départ.' + } + ], + ja: [ + { + id: '1', + title: '軽量でアグノスティック', + description: + '任意のデータソース(REST、GraphQL、またはカスタムフェッチャー)をサポートする小さな API サーフェス。' + }, + { + id: '2', + title: 'リアルタイムで回復力がある', + description: + '自動バックグラウンド再検証、フォーカス/再接続更新、ページネーションとストリーミングのユーティリティ。' + }, + { + id: '3', + title: 'ネイティブ React エルゴノミクス', + description: + 'Suspense 向けに構築され、SSR と SSG と互換性があり、最初から完全に型付けされています。' + } + ], + ko: [ + { + id: '1', + title: '가볍고 독립적', + description: + '모든 데이터 소스(REST, GraphQL 또는 사용자 정의 fetcher)를 지원하는 작은 API 표면.' + }, + { + id: '2', + title: '실시간 및 복원력', + description: + '자동 백그라운드 재검증, 포커스/재연결 업데이트, 페이지네이션 및 스트리밍 유틸리티.' + }, + { + id: '3', + title: '네이티브 React 인체공학', + description: + 'Suspense를 위해 구축되었으며, SSR 및 SSG와 호환되며 처음부터 완전히 타입이 지정되어 있습니다.' + } + ], + pt: [ + { + id: '1', + title: 'Leve e agnóstico', + description: + 'Uma superfície de API pequena com suporte para qualquer fonte de dados — REST, GraphQL ou fetchers personalizados.' + }, + { + id: '2', + title: 'Tempo real e resiliente', + description: + 'Revalidação automática em segundo plano, atualizações de foco/reconexão e utilitários para paginação e streaming.' + }, + { + id: '3', + title: 'Ergonomia React nativa', + description: + 'Construído para Suspense, compatível com SSR e SSG, e totalmente tipado desde o início.' + } + ], + ru: [ + { + id: '1', + title: 'Легковесный и агностичный', + description: + 'Небольшая поверхность API с поддержкой любого источника данных — REST, GraphQL или пользовательских fetchers.' + }, + { + id: '2', + title: 'В реальном времени и отказоустойчивый', + description: + 'Автоматическая фоновая ревалидация, обновления при фокусе/переподключении и утилиты для пагинации и потоковой передачи.' + }, + { + id: '3', + title: 'Нативная эргономика React', + description: + 'Построен для Suspense, совместим с SSR и SSG, полностью типизирован с самого начала.' + } + ], + cn: [ + { + id: '1', + title: '轻量且框架无关', + description: + '小巧的 API 表面,支持任何数据源 — REST、GraphQL 或自定义 fetcher。' + }, + { + id: '2', + title: '实时且具有弹性', + description: + '自动后台重新验证、聚焦/重连更新,以及用于分页和流式传输的工具。' + }, + { + id: '3', + title: '原生 React 人体工程学', + description: + '为 Suspense 构建,与 SSR 和 SSG 兼容,从一开始就完全类型化。' + } + ] +} + +export const cta: Record< + Locale, + { + title: string + cta: string + } +> = { + en: { + title: 'Start building with SWR', + cta: 'Get started' + }, + fr: { + title: 'Commencez à construire avec SWR', + cta: 'Commencer' + }, + ja: { + title: 'SWR で構築を始める', + cta: '始める' + }, + ko: { + title: 'SWR로 구축 시작하기', + cta: '시작하기' + }, + pt: { + title: 'Comece a construir com SWR', + cta: 'Começar' + }, + ru: { + title: 'Начните создавать с SWR', + cta: 'Начать' + }, + cn: { + title: '开始使用 SWR 构建', + cta: '开始使用' + } +} diff --git a/app/[lang]/(home)/layout.tsx b/app/[lang]/(home)/layout.tsx new file mode 100644 index 00000000..cdf234c8 --- /dev/null +++ b/app/[lang]/(home)/layout.tsx @@ -0,0 +1,14 @@ +import { HomeLayout } from "@/components/geistdocs/home-layout"; +import { source } from "@/lib/geistdocs/source"; + +const Layout = async ({ children, params }: LayoutProps<"/[lang]">) => { + const { lang } = await params; + + return ( + +
{children}
+
+ ); +}; + +export default Layout; diff --git a/app/[lang]/(home)/page.tsx b/app/[lang]/(home)/page.tsx new file mode 100644 index 00000000..4236bf2a --- /dev/null +++ b/app/[lang]/(home)/page.tsx @@ -0,0 +1,108 @@ +import DynamicLink from 'fumadocs-core/dynamic-link' +import type { Metadata } from 'next' +import { Installer } from '@/components/geistdocs/installer' +import { Button } from '@/components/ui/button' +import { CenteredSection } from './components/centered-section' +import { CTA } from './components/cta' +import { Hero } from './components/hero' +import { OneTwoSection } from './components/one-two-section' +import { TextGridSection } from './components/text-grid-section' +import { codeToHtml } from 'shiki' +import { cn } from '@/lib/utils' +import { Badge } from '@/components/ui/badge' +import * as copy from './copy' + +export const metadata: Metadata = { + title: copy.metadata.en.title, + description: copy.metadata.en.description +} + +const exampleCode = `import useSWR from 'swr' + +function Profile() { + const { data, error, isLoading } = useSWR('/api/user', fetcher) + + if (error) return
failed to load
+ if (isLoading) return
loading...
+ return
hello {data.name}!
+}` + +const preClassNames = cn('[&_.shiki]:bg-transparent!') + +const darkModeClassNames = cn( + 'dark:[&_.shiki]:text-[var(--shiki-dark)]!', + 'dark:[&_.shiki]:[font-style:var(--shiki-dark-font-style)]!', + 'dark:[&_.shiki]:[font-weight:var(--shiki-dark-font-weight)]!', + 'dark:[&_.shiki]:[text-decoration:var(--shiki-dark-text-decoration)]!', + 'dark:[&_.shiki_span]:text-[var(--shiki-dark)]!', + 'dark:[&_.shiki_span]:[font-style:var(--shiki-dark-font-style)]!', + 'dark:[&_.shiki_span]:[font-weight:var(--shiki-dark-font-weight)]!', + 'dark:[&_.shiki_span]:[text-decoration:var(--shiki-dark-text-decoration)]!' +) + +type PageProps = { + params: Promise<{ + lang: keyof typeof copy.metadata + }> +} + +const HomePage = async ({ params }: PageProps) => { + const { lang } = await params + const code = await codeToHtml(exampleCode, { + lang: 'javascript', + themes: { light: 'github-light', dark: 'github-dark' } + }) + + return ( +
+ +
+ + +
+
+
+ +
+ + +
+ {copy.features[lang].map(feature => ( + + {feature} + + ))} +
+
+ + +
+
+ ) +} + +export default HomePage diff --git a/app/[lang]/blog/[...slug]/page.tsx b/app/[lang]/blog/[...slug]/page.tsx new file mode 100644 index 00000000..4843ebff --- /dev/null +++ b/app/[lang]/blog/[...slug]/page.tsx @@ -0,0 +1,104 @@ +import { createRelativeLink } from 'fumadocs-ui/mdx' +import type { Metadata } from 'next' +import { notFound } from 'next/navigation' +import { AskAI } from '@/components/geistdocs/ask-ai' +import { CopyPage } from '@/components/geistdocs/copy-page' +import { + DocsBody, + DocsDescription, + DocsPage, + DocsTitle +} from '@/components/geistdocs/docs-page' +import { EditSource } from '@/components/geistdocs/edit-source' +import { Feedback } from '@/components/geistdocs/feedback' +import { getMDXComponents } from '@/components/geistdocs/mdx-components' +import { OpenInChat } from '@/components/geistdocs/open-in-chat' +import { ScrollTop } from '@/components/geistdocs/scroll-top' +import { Separator } from '@/components/ui/separator' +import { getLLMText, getPageImage, blogSource } from '@/lib/geistdocs/source' + +import { Bleed } from '@/components/custom/bleed' +import Authors, { Author } from '@/components/custom/authors' +import { Welcome } from '@/components/custom/diagrams/welcome' +import { Pagination } from '@/components/custom/diagrams/pagination' +import { Infinite } from '@/components/custom/diagrams/infinite' +import { Cache } from '@/components/custom/diagrams/cache' +import Link from 'next/link' + +const Page = async ({ params }: PageProps<'/[lang]/blog/[...slug]'>) => { + const { slug, lang } = await params + const page = blogSource.getPage(slug, lang) + + if (!page) { + notFound() + } + + const markdown = await getLLMText(page) + const MDX = page.data.body + + return ( + + + + + + + + +
+ ) + }} + toc={page.data.toc} + > + {page.data.title} + {page.data.description} + + + + + ) +} + +export const generateStaticParams = () => blogSource.generateParams() + +export const generateMetadata = async ({ + params +}: PageProps<'/[lang]/blog/[...slug]'>) => { + const { slug, lang } = await params + const page = blogSource.getPage(slug, lang) + + if (!page) { + notFound() + } + + const metadata: Metadata = { + title: page.data.title, + description: page.data.description, + openGraph: { + images: getPageImage(page).url + } + } + + return metadata +} + +export default Page diff --git a/app/[lang]/blog/layout.tsx b/app/[lang]/blog/layout.tsx new file mode 100644 index 00000000..666407c5 --- /dev/null +++ b/app/[lang]/blog/layout.tsx @@ -0,0 +1,10 @@ +import { DocsLayout } from '@/components/geistdocs/docs-layout' +import { blogSource } from '@/lib/geistdocs/source' + +const Layout = async (props: LayoutProps<'/[lang]/blog'>) => { + const { lang } = await props.params + + return +} + +export default Layout diff --git a/app/[lang]/docs/[[...slug]]/page.tsx b/app/[lang]/docs/[[...slug]]/page.tsx new file mode 100644 index 00000000..ef5b0eef --- /dev/null +++ b/app/[lang]/docs/[[...slug]]/page.tsx @@ -0,0 +1,104 @@ +import { createRelativeLink } from 'fumadocs-ui/mdx' +import type { Metadata } from 'next' +import { notFound } from 'next/navigation' +import { AskAI } from '@/components/geistdocs/ask-ai' +import { CopyPage } from '@/components/geistdocs/copy-page' +import { + DocsBody, + DocsDescription, + DocsPage, + DocsTitle +} from '@/components/geistdocs/docs-page' +import { EditSource } from '@/components/geistdocs/edit-source' +import { Feedback } from '@/components/geistdocs/feedback' +import { getMDXComponents } from '@/components/geistdocs/mdx-components' +import { OpenInChat } from '@/components/geistdocs/open-in-chat' +import { ScrollTop } from '@/components/geistdocs/scroll-top' +import { Separator } from '@/components/ui/separator' +import { getLLMText, getPageImage, source } from '@/lib/geistdocs/source' + +import { Bleed } from '@/components/custom/bleed' +import Authors, { Author } from '@/components/custom/authors' +import { Welcome } from '@/components/custom/diagrams/welcome' +import { Pagination } from '@/components/custom/diagrams/pagination' +import { Infinite } from '@/components/custom/diagrams/infinite' +import { Cache } from '@/components/custom/diagrams/cache' +import Link from 'next/link' + +const Page = async ({ params }: PageProps<'/[lang]/docs/[[...slug]]'>) => { + const { slug, lang } = await params + const page = source.getPage(slug, lang) + + if (!page) { + notFound() + } + + const markdown = await getLLMText(page) + const MDX = page.data.body + + return ( + + + + + + + + + + ) + }} + toc={page.data.toc} + > + {page.data.title} + {page.data.description} + + + + + ) +} + +export const generateStaticParams = () => source.generateParams() + +export const generateMetadata = async ({ + params +}: PageProps<'/[lang]/docs/[[...slug]]'>) => { + const { slug, lang } = await params + const page = source.getPage(slug, lang) + + if (!page) { + notFound() + } + + const metadata: Metadata = { + title: page.data.title, + description: page.data.description, + openGraph: { + images: getPageImage(page).url + } + } + + return metadata +} + +export default Page diff --git a/app/[lang]/docs/layout.tsx b/app/[lang]/docs/layout.tsx new file mode 100644 index 00000000..df146f1e --- /dev/null +++ b/app/[lang]/docs/layout.tsx @@ -0,0 +1,10 @@ +import { DocsLayout } from "@/components/geistdocs/docs-layout"; +import { source } from "@/lib/geistdocs/source"; + +const Layout = async ({ children, params }: LayoutProps<"/[lang]/docs">) => { + const { lang } = await params; + + return {children}; +}; + +export default Layout; diff --git a/app/[lang]/examples/[[...slug]]/page.tsx b/app/[lang]/examples/[[...slug]]/page.tsx new file mode 100644 index 00000000..87ae3efc --- /dev/null +++ b/app/[lang]/examples/[[...slug]]/page.tsx @@ -0,0 +1,108 @@ +import { createRelativeLink } from 'fumadocs-ui/mdx' +import type { Metadata } from 'next' +import { notFound } from 'next/navigation' +import { AskAI } from '@/components/geistdocs/ask-ai' +import { CopyPage } from '@/components/geistdocs/copy-page' +import { + DocsBody, + DocsDescription, + DocsPage, + DocsTitle +} from '@/components/geistdocs/docs-page' +import { EditSource } from '@/components/geistdocs/edit-source' +import { Feedback } from '@/components/geistdocs/feedback' +import { getMDXComponents } from '@/components/geistdocs/mdx-components' +import { OpenInChat } from '@/components/geistdocs/open-in-chat' +import { ScrollTop } from '@/components/geistdocs/scroll-top' +import { Separator } from '@/components/ui/separator' +import { + getLLMText, + getPageImage, + examplesSource +} from '@/lib/geistdocs/source' + +import { Bleed } from '@/components/custom/bleed' +import Authors, { Author } from '@/components/custom/authors' +import { Welcome } from '@/components/custom/diagrams/welcome' +import { Pagination } from '@/components/custom/diagrams/pagination' +import { Infinite } from '@/components/custom/diagrams/infinite' +import { Cache } from '@/components/custom/diagrams/cache' +import Link from 'next/link' + +const Page = async ({ params }: PageProps<'/[lang]/examples/[[...slug]]'>) => { + const { slug, lang } = await params + const page = examplesSource.getPage(slug, lang) + + if (!page) { + notFound() + } + + const markdown = await getLLMText(page) + const MDX = page.data.body + + return ( + + + + + + + + + + ) + }} + toc={page.data.toc} + > + {page.data.title} + {page.data.description} + + + + + ) +} + +export const generateStaticParams = () => examplesSource.generateParams() + +export const generateMetadata = async ({ + params +}: PageProps<'/[lang]/examples/[[...slug]]'>) => { + const { slug, lang } = await params + const page = examplesSource.getPage(slug, lang) + + if (!page) { + notFound() + } + + const metadata: Metadata = { + title: page.data.title, + description: page.data.description, + openGraph: { + images: getPageImage(page).url + } + } + + return metadata +} + +export default Page diff --git a/app/[lang]/examples/layout.tsx b/app/[lang]/examples/layout.tsx new file mode 100644 index 00000000..d1822ffc --- /dev/null +++ b/app/[lang]/examples/layout.tsx @@ -0,0 +1,10 @@ +import { DocsLayout } from '@/components/geistdocs/docs-layout' +import { examplesSource } from '@/lib/geistdocs/source' + +const Layout = async (props: LayoutProps<'/[lang]/examples'>) => { + const { lang } = await props.params + + return +} + +export default Layout diff --git a/app/[lang]/layout.tsx b/app/[lang]/layout.tsx new file mode 100644 index 00000000..19a94217 --- /dev/null +++ b/app/[lang]/layout.tsx @@ -0,0 +1,29 @@ +import "../global.css"; +import { Footer } from "@/components/geistdocs/footer"; +import { Navbar } from "@/components/geistdocs/navbar"; +import { GeistdocsProvider } from "@/components/geistdocs/provider"; +import { basePath } from "@/geistdocs"; +import { mono, sans } from "@/lib/geistdocs/fonts"; +import { cn } from "@/lib/utils"; + +const Layout = async ({ children, params }: LayoutProps<"/[lang]">) => { + const { lang } = await params; + + return ( + + + + + {children} +