From 32b6a425fd5207c3f3d4b77d14d2eb66151edecc Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 30 Jun 2026 15:14:36 -0700 Subject: [PATCH] improvement(landing): SSR-friendly URL-state filters + cleanup pass + polish (#5298) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(landing): cleanup pass — size-* shorthand, drop redundant refs/memos, changelog useInfiniteQuery - emcn: collapse 29 square h-N w-N pairs to size-* across models/integrations/blog/faq/landing-preview - landing-preview: remove redundant animationKeyRef (functional setState) + dead isDesktopRef - model-directory: hoist static provider options to a module const - auth-modal: drop useMemo over the cheap getBrandConfig() call - changelog: replace useState+fetch pagination with a co-located useInfiniteQuery hook (first page stays SSR-seeded via initialData) * feat(landing): URL-state filters via nuqs (SSR-friendly) + stars fallback bump - integrations grid, models directory: search + category/provider filters now live in the URL (nuqs useQueryStates), server-parsed via createSearchParamsCache so filtered views render server-side (crawlable, shareable) — mirrors the blog index SSR pattern. Search URL writes debounced; in-memory filtering stays instant. - pricing: billing-period toggle moves to ?billing=annual (shareable, no flash). - co-located search-params.ts per page as the single source of truth (server + client). - stars: bump fallback floor 28800 -> 28900 to track the current count. * fix(landing): use the light sim mark (not green) in the integration CTA Replace brandbook/logo/small.png — referenced only by the 'Start automating {service} today' CTA on integration pages — with the black-on-light sim mark so the tile reads as a neutral brand mark beside the partner icon instead of a green block. * fix(landing): calmer release-timeline dot hover Drop the scale-150 + brightness-75 hover (a 50% size jump plus a muddy darken) for an understated opacity-fill (0.85 -> 1) with a slight scale-110, matching the comparison chart's opacity-driven hover language. * fix(landing): keep changelog load-more when initial page is empty; drop inline comments - changelog: getNextPageParam no longer treats an empty server-seeded page 1 as end-of-feed, so a failed/empty initial GitHub fetch still surfaces 'Show more' (addresses Cursor Bugbot). - replace the inline comments added in this branch with TSDoc on the search-param caches (documents the dynamic-render → SSR-filtered behavior), per the codebase's TSDoc-only convention. * revert(landing): keep the original changelog timeline (drop useInfiniteQuery) The React Query conversion of an SSR-seeded, cross-origin, infrequently-changing paginated list introduced caching edge cases (empty-seed load-more, singleton cache serving stale page 1 on client-side nav) without real benefit. Restore the original useState(initialEntries)+fetch timeline, which is simpler, correct, and already review-clean from #5181. --- .../(landing)/blog/[slug]/share-button.tsx | 8 +-- .../components/auth-modal/auth-modal.tsx | 4 +- .../components/landing-faq/landing-faq.tsx | 2 +- .../landing-preview-home.tsx | 14 +++--- .../landing-preview-logs.tsx | 2 +- .../preview-block-node.tsx | 4 +- .../landing-preview/landing-preview.tsx | 9 +--- .../integrations/(shell)/[slug]/page.tsx | 6 +-- .../(landing)/integrations/(shell)/page.tsx | 10 +++- .../components/integration-card.tsx | 2 +- .../components/integration-grid.tsx | 24 ++++++--- .../components/integration-icon.tsx | 6 +-- .../(landing)/integrations/search-params.ts | 30 ++++++++++++ .../(shell)/[provider]/[model]/page.tsx | 2 +- .../models/(shell)/[provider]/page.tsx | 2 +- .../sim/app/(landing)/models/(shell)/page.tsx | 10 +++- .../models/components/model-directory.tsx | 46 ++++++++++-------- .../models/components/model-primitives.tsx | 6 +-- .../components/model-timeline-chart.tsx | 6 +-- .../sim/app/(landing)/models/search-params.ts | 30 ++++++++++++ .../pricing-plans/pricing-plans.tsx | 7 ++- apps/sim/app/(landing)/pricing/page.tsx | 5 +- .../app/(landing)/pricing/search-params.ts | 28 +++++++++++ apps/sim/lib/github/stars.ts | 9 +++- apps/sim/public/brandbook/logo/small.png | Bin 16602 -> 17424 bytes 25 files changed, 198 insertions(+), 74 deletions(-) create mode 100644 apps/sim/app/(landing)/integrations/search-params.ts create mode 100644 apps/sim/app/(landing)/models/search-params.ts create mode 100644 apps/sim/app/(landing)/pricing/search-params.ts diff --git a/apps/sim/app/(landing)/blog/[slug]/share-button.tsx b/apps/sim/app/(landing)/blog/[slug]/share-button.tsx index 91f3ee0871..5f88b24edd 100644 --- a/apps/sim/app/(landing)/blog/[slug]/share-button.tsx +++ b/apps/sim/app/(landing)/blog/[slug]/share-button.tsx @@ -41,21 +41,21 @@ export function ShareButton({ url, title }: ShareButtonProps) { className='flex items-center gap-1.5 text-[var(--text-muted)] text-sm hover:text-[var(--text-primary)]' aria-label='Share this post' > - + Share - + {copied ? 'Copied!' : 'Copy link'} - + Share on X - + Share on LinkedIn diff --git a/apps/sim/app/(landing)/components/auth-modal/auth-modal.tsx b/apps/sim/app/(landing)/components/auth-modal/auth-modal.tsx index bb20ed19fe..48b0c197bb 100644 --- a/apps/sim/app/(landing)/components/auth-modal/auth-modal.tsx +++ b/apps/sim/app/(landing)/components/auth-modal/auth-modal.tsx @@ -1,6 +1,6 @@ 'use client' -import { useEffect, useMemo, useState } from 'react' +import { useEffect, useState } from 'react' import { Loader, Modal, @@ -69,7 +69,7 @@ export function AuthModal({ children, defaultView = 'login', source }: AuthModal const [view, setView] = useState(defaultView) const [providerStatus, setProviderStatus] = useState(null) const [socialLoading, setSocialLoading] = useState<'github' | 'google' | 'microsoft' | null>(null) - const brand = useMemo(() => getBrandConfig(), []) + const brand = getBrandConfig() useEffect(() => { fetchProviderStatus().then(setProviderStatus) diff --git a/apps/sim/app/(landing)/components/landing-faq/landing-faq.tsx b/apps/sim/app/(landing)/components/landing-faq/landing-faq.tsx index 39a5492e21..1546588e00 100644 --- a/apps/sim/app/(landing)/components/landing-faq/landing-faq.tsx +++ b/apps/sim/app/(landing)/components/landing-faq/landing-faq.tsx @@ -61,7 +61,7 @@ export function LandingFAQ({ faqs }: LandingFAQProps) {