From 00133341cb3d5b2f4d24a0dd0b1647d6b89942c8 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Fri, 26 Jan 2024 15:15:13 +1100 Subject: [PATCH 01/12] Update redirect banner, remove unnecessary redirects, stackblitz iframe --- app/components/RedirectVersionBanner.tsx | 68 +++++------ app/routes/_index.tsx | 2 +- app/routes/form.$version._index.tsx | 71 ++++------- ...n.docs.framework.$framework.examples.$.tsx | 9 +- app/routes/form.$version.tsx | 64 ++++------ app/routes/query.$.tsx | 111 +----------------- app/routes/query.$version._index.tsx | 22 ++-- ...n.docs.framework.$framework.examples.$.tsx | 7 +- app/routes/query.$version.tsx | 52 ++++---- app/routes/ranger.$version._index.tsx | 17 ++- ...r.$version.docs.framework.$framework.$.tsx | 2 +- ...n.docs.framework.$framework.examples.$.tsx | 9 +- app/routes/ranger.$version.tsx | 52 ++++---- app/routes/router.$.tsx | 31 +---- app/routes/router.$version._index.tsx | 21 ++-- ...n.docs.framework.$framework.examples.$.tsx | 9 +- app/routes/router.$version.tsx | 52 ++++---- app/routes/store.$version._index.tsx | 12 +- app/routes/store.$version.tsx | 64 ++++------ app/routes/table.$.tsx | 54 +-------- app/routes/table.$version._index.tsx | 15 +-- app/routes/table.$version.tsx | 55 ++++----- app/routes/virtual.$.tsx | 35 +----- app/routes/virtual.$version._index.tsx | 14 +-- app/routes/virtual.$version.tsx | 55 ++++----- 25 files changed, 279 insertions(+), 624 deletions(-) diff --git a/app/components/RedirectVersionBanner.tsx b/app/components/RedirectVersionBanner.tsx index 8be0b7d1..e9eb8fbe 100644 --- a/app/components/RedirectVersionBanner.tsx +++ b/app/components/RedirectVersionBanner.tsx @@ -1,12 +1,13 @@ -import { Link, useLocation } from '@remix-run/react' +import { Link } from '@remix-run/react' import { useLocalStorage } from '~/utils/useLocalStorage' import { useClientOnlyRender } from '~/utils/useClientOnlyRender' export function RedirectVersionBanner(props: { - currentVersion: string + version: string latestVersion: string + redirectUrl: string }) { - const location = useLocation() + const { version, latestVersion, redirectUrl } = props // After user clicks hide, do not show modal for a month, and then remind users that there is a new version! const [showModal, setShowModal] = useLocalStorage( @@ -15,44 +16,35 @@ export function RedirectVersionBanner(props: { 1000 * 60 * 24 * 30 ) - const isLowerVersion = - Number(props.currentVersion) < Number(props.latestVersion[1]) - const redirectTarget = location.pathname.replace( - `v${props.currentVersion}`, - 'latest' - ) - if (!useClientOnlyRender()) { return null } - return ( - <> - {isLowerVersion && showModal ? ( -
-
- You are currently reading v{props.currentVersion}{' '} - docs. Redirect to{' '} - - latest - {' '} - version? -
- - Latest - - + if (![latestVersion, 'latest'].includes(version) && showModal) { + return ( +
+
+ You are currently reading v{version} docs. Redirect + to{' '} + + latest + {' '} + version?
- ) : null} - - ) + + Latest + + +
+ ) + } } diff --git a/app/routes/_index.tsx b/app/routes/_index.tsx index b80795ec..cf685927 100644 --- a/app/routes/_index.tsx +++ b/app/routes/_index.tsx @@ -559,7 +559,7 @@ export default function Index() { right-0 top-0 -translate-y-1/3 translate-x-1/3 sm:opacity-20`} > - + Discord

TanStack on Discord

diff --git a/app/routes/form.$version._index.tsx b/app/routes/form.$version._index.tsx index f1ddc7b1..3fd6c0f1 100644 --- a/app/routes/form.$version._index.tsx +++ b/app/routes/form.$version._index.tsx @@ -11,7 +11,7 @@ import { FaTshirt, } from 'react-icons/fa' import { json } from '@remix-run/node' -import { Link, useLoaderData, useParams } from '@remix-run/react' +import { Link, useLoaderData } from '@remix-run/react' import { Carbon } from '~/components/Carbon' import { Footer } from '~/components/Footer' import { VscPreview, VscWand } from 'react-icons/vsc' @@ -27,6 +27,7 @@ import { import { Logo } from '~/components/Logo' import { getSponsorsForSponsorPack } from '~/server/sponsors' import type { Framework } from '~/projects/form' +import type { LoaderFunctionArgs } from '@remix-run/node' const menu = [ { @@ -79,17 +80,18 @@ const menu = [ }, ] -export const loader = async () => { +export const loader = async (context: LoaderFunctionArgs) => { + const { version } = context.params const sponsors = await getSponsorsForSponsorPack() return json({ sponsors, + version, }) } export default function RouteVersion() { - const { sponsors } = useLoaderData() - const { version } = useParams() + const { sponsors, version } = useLoaderData() const branch = getBranch(version) const [framework, setFramework] = React.useState('react') const [isDark, setIsDark] = React.useState(true) @@ -373,15 +375,7 @@ export default function RouteVersion() { ? 'bg-yellow-500' : 'bg-gray-300 dark:bg-gray-700 hover:bg-yellow-400' }`} - onClick={ - () => setFramework(item.value) - // setParams(new URLSearchParams({ framework: item.value }), { - // replace: true, - // state: { - // scroll: false, - // }, - // }) - } + onClick={() => setFramework(item.value)} > {item.label} @@ -390,40 +384,23 @@ export default function RouteVersion() {
- {[].includes(framework) ? ( -
-
- Looking for the @tanstack/{framework}-form{' '} - example? We could use your help to build the{' '} - @tanstack/{framework}-form adapter! Join the{' '} - - TanStack Discord Server - {' '} - and let's get to work! -
-
- ) : ( -
- -
- )} +
+ +
diff --git a/app/routes/form.$version.docs.framework.$framework.examples.$.tsx b/app/routes/form.$version.docs.framework.$framework.examples.$.tsx index ca4613c3..6e376ab0 100644 --- a/app/routes/form.$version.docs.framework.$framework.examples.$.tsx +++ b/app/routes/form.$version.docs.framework.$framework.examples.$.tsx @@ -1,7 +1,7 @@ import React from 'react' import type { LoaderFunctionArgs, MetaFunction } from '@remix-run/node' import { json } from '@remix-run/node' -import { useLoaderData, useParams } from '@remix-run/react' +import { useLoaderData } from '@remix-run/react' import { DocTitle } from '~/components/DocTitle' import { repo, getBranch } from '~/projects/form' import { seo } from '~/utils/seo' @@ -9,9 +9,9 @@ import { capitalize, slugToTitle } from '~/utils/utils' import { FaExternalLinkAlt } from 'react-icons/fa' export const loader = async (context: LoaderFunctionArgs) => { - const { framework, '*': name } = context.params + const { version, framework, '*': name } = context.params - return json({ framework, name }) + return json({ version, framework, name }) } export const meta: MetaFunction = ({ data }) => { @@ -26,8 +26,7 @@ export const meta: MetaFunction = ({ data }) => { } export default function RouteExamples() { - const { framework, name } = useLoaderData() - const { version } = useParams() + const { version, framework, name } = useLoaderData() const branch = getBranch(version) const examplePath = [framework, name].join('/') diff --git a/app/routes/form.$version.tsx b/app/routes/form.$version.tsx index 77831c2a..010f9890 100644 --- a/app/routes/form.$version.tsx +++ b/app/routes/form.$version.tsx @@ -1,23 +1,29 @@ -import { Link, Outlet, useLocation } from '@remix-run/react' +import { Outlet, json, redirect, useLoaderData } from '@remix-run/react' import { DefaultErrorBoundary } from '~/components/DefaultErrorBoundary' -import { useLocalStorage } from '~/utils/useLocalStorage' import { useClientOnlyRender } from '~/utils/useClientOnlyRender' -import { latestVersion } from '~/projects/form' +import { availableVersions, latestVersion } from '~/projects/form' +import type { LoaderFunctionArgs } from '@remix-run/node' +import { RedirectVersionBanner } from '~/components/RedirectVersionBanner' + +export const loader = async (context: LoaderFunctionArgs) => { + const { version } = context.params + + const redirectUrl = context.request.url.replace(version!, 'latest') + + if (!availableVersions.concat('latest').includes(version!)) { + throw redirect(redirectUrl) + } + + return json({ + version, + redirectUrl, + }) +} export const ErrorBoundary = DefaultErrorBoundary export default function RouteVersionParam() { - // After user clicks hide, do not show modal for a month, and then remind users that there is a new version! - const [showModal, setShowModal] = useLocalStorage( - 'showRedirectToLatestModal', - true, - 1000 * 60 * 24 * 30 - ) - const location = useLocation() - - const version = location.pathname.match(/\/form\/v(\d)/)?.[1] || '999' - const isLowerVersion = Number(version) < Number(latestVersion[1]) - const redirectTarget = location.pathname.replace(`v${version}`, 'latest') + const { version, redirectUrl } = useLoaderData() if (!useClientOnlyRender()) { return null @@ -25,31 +31,11 @@ export default function RouteVersionParam() { return ( <> - {isLowerVersion && showModal ? ( -
-
- You are currently reading v{version} docs. Redirect - to{' '} - - latest - {' '} - version? -
- - Latest - - -
- ) : null} + ) diff --git a/app/routes/query.$.tsx b/app/routes/query.$.tsx index 506a1fc7..5b5d97d2 100644 --- a/app/routes/query.$.tsx +++ b/app/routes/query.$.tsx @@ -1,112 +1,5 @@ import { redirect } from '@remix-run/node' -import type { LoaderFunctionArgs } from '@remix-run/node' -export const loader = (context: LoaderFunctionArgs) => { - handleRedirectsFromV3(context) - - return redirect(`/query/latest`) -} - -function handleRedirectsFromV3(context: LoaderFunctionArgs) { - const url = new URL(context.request.url) - - // Redirect old query v3 docs - // prettier-ignore - const reactQueryv3List = [ - // {from: 'api/overview',to: 'docs/guide/overview',}, - {from: "overview", to: "docs/overview"}, - {from: "installation", to: "docs/installation"}, - {from: "quick-start", to: "docs/quick-start"}, - {from: "devtools", to: "docs/devtools"}, - {from: "videos", to: "docs/videos"}, - {from: "comparison", to: "docs/comparison"}, - {from: "typescript", to: "docs/typescript"}, - {from: "graphql", to: "docs/graphql"}, - {from: "react-native", to: "docs/react-native"}, - {from: "guides/important-defaults", to: "docs/guides/important-defaults"}, - {from: "guides/queries", to: "docs/guides/queries"}, - {from: "guides/query-keys", to: "docs/guides/query-keys"}, - {from: "guides/query-functions", to: "docs/guides/query-functions"}, - {from: "guides/network-mode", to: "docs/guides/network-mode"}, - {from: "guides/parallel-queries", to: "docs/guides/parallel-queries"}, - {from: "guides/dependent-queries", to: "docs/guides/dependent-queries"}, - {from: "guides/background-fetching-indicators", to: "docs/guides/background-fetching-indicators"}, - {from: "guides/window-focus-refetching", to: "docs/guides/window-focus-refetching"}, - {from: "guides/disabling-queries", to: "docs/guides/disabling-queries"}, - {from: "guides/query-retries", to: "docs/guides/query-retries"}, - {from: "guides/paginated-queries", to: "docs/guides/paginated-queries"}, - {from: "guides/infinite-queries", to: "docs/guides/infinite-queries"}, - {from: "guides/placeholder-query-data", to: "docs/guides/placeholder-query-data"}, - {from: "guides/initial-query-data", to: "docs/guides/initial-query-data"}, - {from: "guides/prefetching", to: "docs/guides/prefetching"}, - {from: "guides/mutations", to: "docs/guides/mutations"}, - {from: "guides/query-invalidation", to: "docs/guides/query-invalidation"}, - {from: "guides/invalidations-from-mutations", to: "docs/guides/invalidations-from-mutations"}, - {from: "guides/updates-from-mutation-responses", to: "docs/guides/updates-from-mutation-responses"}, - {from: "guides/optimistic-updates", to: "docs/guides/optimistic-updates"}, - {from: "guides/query-cancellation", to: "docs/guides/query-cancellation"}, - {from: "guides/scroll-restoration", to: "docs/guides/scroll-restoration"}, - {from: "guides/filters", to: "docs/guides/filters"}, - {from: "guides/ssr", to: "docs/guides/ssr"}, - {from: "guides/caching", to: "docs/guides/caching"}, - {from: "guides/default-query-function", to: "docs/guides/default-query-function"}, - {from: "guides/suspense", to: "docs/guides/suspense"}, - {from: "guides/custom-logger", to: "docs/guides/custom-logger"}, - {from: "guides/testing", to: "docs/guides/testing"}, - {from: "guides/does-this-replace-client-state", to: "docs/guides/does-this-replace-client-state"}, - {from: "guides/migrating-to-react-query-3", to: "docs/guides/migrating-to-react-query-3"}, - {from: "guides/migrating-to-react-query-4", to: "docs/guides/migrating-to-react-query-4"}, - {from: "community/tkdodos-blog", to: "docs/community/tkdodos-blog"}, - {from: "examples/simple", to: "docs/examples/react/simple"}, - {from: "examples/basic", to: "docs/examples/react/basic"}, - {from: "examples/basic-graphql-request", to: "docs/examples/react/basic-graphql-request"}, - {from: "examples/custom-hooks", to: "docs/examples/react/custom-hooks"}, - {from: "examples/auto-refetching", to: "docs/examples/react/auto-refetching"}, - {from: "examples/focus-refetching", to: "docs/examples/react/focus-refetching"}, - {from: "examples/optimistic-updates", to: "docs/examples/react/optimistic-updates-typescript"}, - {from: "examples/optimistic-updates-typescript", to: "docs/examples/react/optimistic-updates-typescript"}, - {from: "examples/pagination", to: "docs/examples/react/pagination"}, - {from: "examples/load-more-infinite-scroll", to: "docs/examples/react/load-more-infinite-scroll"}, - {from: "examples/suspense", to: "docs/examples/react/suspense"}, - {from: "examples/default-query-function", to: "docs/examples/react/default-query-function"}, - {from: "examples/playground", to: "docs/examples/react/playground"}, - {from: "examples/prefetching", to: "docs/examples/react/prefetching"}, - {from: "examples/star-wars", to: "docs/examples/react/star-wars"}, - {from: "examples/rick-morty", to: "docs/examples/react/rick-morty"}, - {from: "examples/nextjs", to: "docs/examples/react/nextjs"}, - {from: "examples/react-native", to: "docs/examples/react/react-native"}, - {from: "examples/offline", to: "docs/examples/react/offline"}, - {from: "plugins/persistQueryClient", to: "docs/plugins/persistQueryClient"}, - {from: "plugins/createWebStoragePersister", to: "docs/plugins/createWebStoragePersister"}, - {from: "plugins/createAsyncStoragePersister", to: "docs/plugins/createAsyncStoragePersister"}, - {from: "plugins/broadcastQueryClient", to: "docs/plugins/broadcastQueryClient"}, - {from: "reference/useQuery", to: "docs/reference/useQuery"}, - {from: "reference/useQueries", to: "docs/reference/useQueries"}, - {from: "reference/useInfiniteQuery", to: "docs/reference/useInfiniteQuery"}, - {from: "reference/useMutation", to: "docs/reference/useMutation"}, - {from: "reference/useIsFetching", to: "docs/reference/useIsFetching"}, - {from: "reference/useIsMutating", to: "docs/reference/useIsMutating"}, - {from: "reference/QueryClient", to: "docs/reference/QueryClient"}, - {from: "reference/QueryClientProvider", to: "docs/reference/QueryClientProvider"}, - {from: "reference/useQueryClient", to: "docs/reference/useQueryClient"}, - {from: "reference/QueryCache", to: "docs/reference/QueryCache"}, - {from: "reference/MutationCache", to: "docs/reference/MutationCache"}, - {from: "reference/QueryObserver", to: "docs/reference/QueryObserver"}, - {from: "reference/InfiniteQueryObserver", to: "docs/reference/InfiniteQueryObserver"}, - {from: "reference/QueriesObserver", to: "docs/reference/QueriesObserver"}, - {from: "reference/QueryErrorResetBoundary", to: "docs/reference/QueryErrorResetBoundary"}, - {from: "reference/useQueryErrorResetBoundary", to: "docs/reference/useQueryErrorResetBoundary"}, - {from: "reference/focusManager", to: "docs/reference/focusManager"}, - {from: "reference/onlineManager", to: "docs/reference/onlineManager"}, - {from: "reference/hydration", to: "docs/reference/hydration"}, - // {from: '',to: ''}, - ] - - reactQueryv3List.forEach((item) => { - if (url.pathname.startsWith(`/query/v3/${item.from}`)) { - throw redirect( - `/query/latest/${item.to}?from=reactQueryV3&original=https://tanstack.com/query/v3/${item.to}` - ) - } - }) +export const loader = () => { + return redirect('/query/latest') } diff --git a/app/routes/query.$version._index.tsx b/app/routes/query.$version._index.tsx index ad73ad52..9b7b92f7 100644 --- a/app/routes/query.$version._index.tsx +++ b/app/routes/query.$version._index.tsx @@ -11,7 +11,7 @@ import { FaTshirt, } from 'react-icons/fa' import { json } from '@remix-run/node' -import { Link, useLoaderData, useParams } from '@remix-run/react' +import { Link, useLoaderData } from '@remix-run/react' import { Carbon } from '~/components/Carbon' import { Footer } from '~/components/Footer' import { VscPreview, VscWand } from 'react-icons/vsc' @@ -29,6 +29,7 @@ import { Logo } from '~/components/Logo' import { LogoQueryGG } from '~/components/LogoQueryGG' import { getSponsorsForSponsorPack } from '~/server/sponsors' import type { Framework } from '~/projects/query' +import type { LoaderFunctionArgs } from '@remix-run/node' const menu = [ { @@ -81,17 +82,18 @@ const menu = [ }, ] -export const loader = async () => { +export const loader = async (context: LoaderFunctionArgs) => { + const { version } = context.params const sponsors = await getSponsorsForSponsorPack() return json({ sponsors, + version, }) } export default function RouteVersion() { - const { sponsors } = useLoaderData() - const { version } = useParams() + const { sponsors, version } = useLoaderData() const branch = getBranch(version) const [framework, setFramework] = React.useState('react') const [isDark, setIsDark] = React.useState(true) @@ -497,15 +499,7 @@ export default function RouteVersion() { ? 'bg-red-500' : 'bg-gray-300 dark:bg-gray-700 hover:bg-red-300' }`} - onClick={ - () => setFramework(item.value) - // setParams(new URLSearchParams({ framework: item.value }), { - // replace: true, - // state: { - // scroll: false, - // }, - // }) - } + onClick={() => setFramework(item.value)} > {item.label} @@ -533,7 +527,7 @@ export default function RouteVersion() {