Skip to content

Commit 01ed775

Browse files
authored
doc: registry error handling (#1212)
1 parent 8ccacea commit 01ed775

File tree

11 files changed

+71
-30
lines changed

11 files changed

+71
-30
lines changed

.github/workflows/ci-cd.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,9 @@ jobs:
410410
echo "version=$VERSION" >> $GITHUB_OUTPUT
411411
echo "Released version: $VERSION"
412412
working-directory: packages/nuqs
413-
- name: Invalidate ISR caches in the docs
413+
- name: Invalidate contributors ISR cache in the docs
414414
if: ${{ github.event_name == 'push' && github.ref_name == 'master' }}
415415
run: |
416-
curl -s "https://nuqs.dev/api/isr?tag=npm-version&token=${{ secrets.ISR_TOKEN }}"
417416
curl -s "https://nuqs.dev/api/isr?tag=contributors&token=${{ secrets.ISR_TOKEN }}"
418417
- name: Install dependencies
419418
if: ${{ github.event_name == 'push' && steps.package-version.outputs.version != '0.0.0-semantically-released' }}

packages/docs/src/app/(pages)/stats/lib/npm.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export async function fetchNpmPackage(
133133
async function get(url: string): Promise<unknown> {
134134
const res = await fetch(url, {
135135
next: {
136-
revalidate: 86_400,
136+
revalidate: 6 * 60 * 60, // 6 hours
137137
tags: ['npm-stats']
138138
}
139139
})

packages/docs/src/app/api/isr/route.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const ACCEPTED_TAGS = [
55
'github',
66
'github-actions-status',
77
'npm-stats',
8-
'npm-version',
98
'contributors'
109
]
1110

packages/docs/src/app/docs/layout.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { source } from '@/src/app/source'
22
import { getSharedLayoutProps } from '@/src/components/shared-layout'
33
import { SidebarFooter } from '@/src/components/sidebar-footer'
44
import { DocsLayout } from 'fumadocs-ui/layouts/notebook'
5-
import { type ReactNode } from 'react'
5+
import { Suspense, type ReactNode } from 'react'
66

77
export default function RootDocsLayout({ children }: { children: ReactNode }) {
88
const shared = getSharedLayoutProps()
@@ -15,7 +15,11 @@ export default function RootDocsLayout({ children }: { children: ReactNode }) {
1515
sidebar={{
1616
collapsible: false,
1717
// banner: // note: side banner goes here
18-
footer: <SidebarFooter />
18+
footer: (
19+
<Suspense>
20+
<SidebarFooter />
21+
</Suspense>
22+
)
1923
}}
2024
>
2125
{children}

packages/docs/src/app/registry/[name]/opengraph-image.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@ export { contentType, size } from '@/src/components/og-image'
77
export const dynamic = 'force-static'
88

99
export async function generateStaticParams(): Promise<{ name: string }[]> {
10-
const registry = await readRegistry()
10+
const [registry, error] = await readRegistry()
11+
if (error || !registry) {
12+
notFound()
13+
}
1114
return registry.items.map(item => ({ name: item.name }))
1215
}
1316

1417
// Image generation
1518
export default async function Image({ params }: PageProps<'/registry/[name]'>) {
1619
const { name } = await params
17-
const item = await readRegistryItem(name).catch(notFound)
18-
20+
const [item, error] = await readRegistryItem(name).catch(notFound)
21+
if (error || !item) {
22+
notFound()
23+
}
1924
return generateOpengraphImage({
2025
title: item.title,
2126
description: item.description

packages/docs/src/app/registry/[name]/page.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ import remarkSmartypants from 'remark-smartypants'
2929

3030
export default async function Page({ params }: PageProps<'/registry/[name]'>) {
3131
const { name } = await params
32-
const { title, description, files } =
33-
await readRegistryItem(name).catch(notFound)
32+
const [item, error] = await readRegistryItem(name)
33+
if (error || !item) {
34+
notFound()
35+
}
36+
const { title, description, files } = item
3437
const category = getRegistryItemCategory(name)
3538
const usage = await readUsage(name)
3639
return (
@@ -84,15 +87,21 @@ export default async function Page({ params }: PageProps<'/registry/[name]'>) {
8487
}
8588

8689
export async function generateStaticParams() {
87-
const registry = await readRegistry()
90+
const [registry, error] = await readRegistry()
91+
if (error || !registry) {
92+
notFound()
93+
}
8894
return registry.items.map(item => ({ name: item.name }))
8995
}
9096

9197
export async function generateMetadata({
9298
params
9399
}: PageProps<'/registry/[name]'>) {
94100
const { name } = await params
95-
const item = await readRegistryItem(name)
101+
const [item, error] = await readRegistryItem(name)
102+
if (error || !item) {
103+
notFound()
104+
}
96105
return {
97106
title: item.title,
98107
description: item.description,

packages/docs/src/app/registry/layout.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { SidebarFooter } from '@/src/components/sidebar-footer'
33
import { categorizeRegistryItems, readRegistry } from '@/src/registry/read'
44
import { DocsLayout } from 'fumadocs-ui/layouts/notebook'
55
import type { Metadata } from 'next'
6+
import { notFound } from 'next/navigation'
67
import { Suspense, type ReactNode } from 'react'
78

89
export const metadata = {
@@ -24,7 +25,10 @@ export default async function RegistryLayout({
2425
children: ReactNode
2526
}) {
2627
const sharedLayoutProps = getSharedLayoutProps()
27-
const registry = await readRegistry()
28+
const [registry, error] = await readRegistry()
29+
if (error || !registry) {
30+
notFound()
31+
}
2832
const categories = categorizeRegistryItems(registry)
2933
return (
3034
<>

packages/docs/src/app/registry/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export default function Page() {
2626
<a href="https://ui.shadcn.com/docs/cli" className="underline">
2727
shadcn CLI
2828
</a>{' '}
29-
to install custom parsers, adapters and utilities from the community.
29+
to install custom parsers, adapters, and utilities from the community.
3030
</DocsDescription>
3131
<DocsBody>
3232
<H2 id="using-the-registry">Using the registry</H2>

packages/docs/src/app/registry/rss.xml/route.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getLastModified } from '@/src/lib/get-last-modified'
22
import { readRegistry } from '@/src/registry/read'
3+
import { notFound } from 'next/navigation'
34

45
export const dynamic = 'force-static'
56

@@ -14,7 +15,10 @@ export async function GET() {
1415

1516
async function generateRssXml() {
1617
const baseUrl = 'https://nuqs.dev/registry'
17-
const registry = await readRegistry()
18+
const [registry, error] = await readRegistry()
19+
if (error || !registry) {
20+
notFound()
21+
}
1822
const items = await Promise.all(
1923
registry.items.map(async item => {
2024
return `<item>

packages/docs/src/components/sidebar-footer.tsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
export async function SidebarFooter() {
2-
const version = await getLatestVersion()
1+
'use client'
2+
3+
import { useEffect, useState } from 'react'
4+
5+
export function SidebarFooter() {
6+
const [version, setVersion] = useState<string | null>(null)
7+
useEffect(() => {
8+
getLatestVersion().then(setVersion).catch(console.error)
9+
}, [])
10+
if (!version) return null
311
return (
4-
<footer className="flex w-full items-baseline gap-2 text-zinc-600 dark:text-zinc-400">
12+
<footer className="ml-2 flex w-full items-baseline gap-2 text-zinc-600 dark:text-zinc-400">
513
<a
614
href={`https://npmjs.com/package/nuqs/v/${version}`}
715
className="hover:underline"
@@ -15,11 +23,9 @@ export async function SidebarFooter() {
1523

1624
async function getLatestVersion() {
1725
try {
18-
const res = await fetch('https://registry.npmjs.org/nuqs', {
19-
next: {
20-
tags: ['npm-version']
21-
}
22-
}).then(r => r.json())
26+
const res = await fetch('https://registry.npmjs.org/nuqs').then(r =>
27+
r.json()
28+
)
2329
return res['dist-tags'].latest
2430
} catch {
2531
return 'latest'

0 commit comments

Comments
 (0)