Skip to content

Commit ecdf4da

Browse files
committed
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.
1 parent fe345b4 commit ecdf4da

8 files changed

Lines changed: 22 additions & 15 deletions

File tree

apps/sim/app/(landing)/changelog/components/changelog-timeline/use-changelog-releases.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,17 @@ async function fetchReleasesPage(page: number, signal?: AbortSignal): Promise<Ch
3131
* page 1 and passes it as `initialEntries`, seeded here via `initialData` so the
3232
* first page stays server-rendered (no client refetch within `staleTime`); the
3333
* "Show more" control drives `fetchNextPage`. A page that maps to zero entries
34-
* (end of releases, or all prereleases) ends pagination — matching the prior
35-
* load-more behavior.
34+
* ends pagination, except the server-seeded page 1 alone — so a failed or empty
35+
* initial fetch still surfaces "Show more" and can load page 2, matching the
36+
* prior client pagination.
3637
*/
3738
export function useChangelogReleases(initialEntries: ChangelogEntry[]) {
3839
return useInfiniteQuery({
3940
queryKey: changelogKeys.releases(),
4041
queryFn: ({ pageParam, signal }) => fetchReleasesPage(pageParam, signal),
4142
initialPageParam: 1,
4243
getNextPageParam: (lastPage, allPages) =>
43-
lastPage.length === 0 ? undefined : allPages.length + 1,
44+
lastPage.length === 0 && allPages.length > 1 ? undefined : allPages.length + 1,
4445
initialData: { pages: [initialEntries], pageParams: [1] },
4546
staleTime: 60 * 60 * 1000,
4647
})

apps/sim/app/(landing)/integrations/(shell)/page.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,6 @@ export default async function IntegrationsPage({
9494
}: {
9595
searchParams: Promise<SearchParams>
9696
}) {
97-
// Parse on the server so the route renders dynamically with the active
98-
// search/category from the URL — the client grid (`useQueryStates`) hydrates in
99-
// sync, keeping filtered views crawlable and shareable.
10097
await integrationsSearchParamsCache.parse(searchParams)
10198

10299
const breadcrumbJsonLd = {

apps/sim/app/(landing)/integrations/search-params.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,10 @@ export const integrationsUrlKeys = {
2121
clearOnDefault: true,
2222
} as const
2323

24+
/**
25+
* Parsing this in the page's server component opts the route into dynamic
26+
* rendering, which populates `useSearchParams` during the server render — so the
27+
* client grid's `useQueryStates` filters server-side and the initial HTML ships
28+
* the filtered catalog (crawlable, shareable), with no post-hydration swap.
29+
*/
2430
export const integrationsSearchParamsCache = createSearchParamsCache(integrationsParsers)

apps/sim/app/(landing)/models/(shell)/page.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,6 @@ export default async function ModelsPage({
8787
}: {
8888
searchParams: Promise<SearchParams>
8989
}) {
90-
// Parse on the server so the route renders dynamically with the active
91-
// search/provider from the URL — the client directory (`useQueryStates`)
92-
// hydrates in sync, keeping filtered views crawlable and shareable.
9390
await modelsSearchParamsCache.parse(searchParams)
9491

9592
const flatModels = MODEL_PROVIDERS_WITH_CATALOGS.flatMap((provider) =>

apps/sim/app/(landing)/models/components/model-timeline-chart.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,6 @@ export function ModelTimelineChart({ models, providerId }: ModelTimelineChartPro
7676
height: '100%',
7777
}}
7878
>
79-
{/* Dot - centered exactly on the line (70px - 6px). Resting at 85%
80-
opacity, hover lifts it to full with a slight scale — an
81-
understated, opacity-driven hover matching the comparison
82-
chart, so it reads as a clean accent rather than a jump. */}
8379
<div
8480
className='-translate-x-1/2 absolute top-[64px] left-1/2 size-[12px] rounded-full opacity-[0.85] transition-[opacity,transform] duration-150 group-hover:scale-110 group-hover:opacity-100'
8581
style={{ backgroundColor: color }}

apps/sim/app/(landing)/models/search-params.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,10 @@ export const modelsUrlKeys = {
2121
clearOnDefault: true,
2222
} as const
2323

24+
/**
25+
* Parsing this in the page's server component opts the route into dynamic
26+
* rendering, which populates `useSearchParams` during the server render — so the
27+
* client directory's `useQueryStates` filters server-side and the initial HTML
28+
* ships the filtered list (crawlable, shareable), with no post-hydration swap.
29+
*/
2430
export const modelsSearchParamsCache = createSearchParamsCache(modelsParsers)

apps/sim/app/(landing)/pricing/page.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ export const metadata: Metadata = {
6161
}
6262

6363
export default async function Page({ searchParams }: { searchParams: Promise<SearchParams> }) {
64-
// Parse on the server so the route renders dynamically with the billing period
65-
// from the URL — the client toggle (`useQueryStates`) then hydrates in sync.
6664
await pricingSearchParamsCache.parse(searchParams)
6765
return <Pricing />
6866
}

apps/sim/app/(landing)/pricing/search-params.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,10 @@ export const pricingUrlKeys = {
1919
clearOnDefault: true,
2020
} as const
2121

22+
/**
23+
* Parsing this in the page's server component opts the route into dynamic
24+
* rendering, which populates `useSearchParams` during the server render — so the
25+
* client cards' `useQueryStates` resolves the billing period server-side and the
26+
* initial HTML ships the correct prices (no toggle flash on a shared link).
27+
*/
2228
export const pricingSearchParamsCache = createSearchParamsCache(pricingParsers)

0 commit comments

Comments
 (0)