-
-
Notifications
You must be signed in to change notification settings - Fork 21
docs: Migrate to Fumadocs #62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
c09cb4e
feat(docs): scaffold Fumadocs app shell, remove Docusaurus
mfkrause 591db08
feat(docs): migrate authored content to MDX
mfkrause 31d3cd7
feat(docs): generate API reference from TypeDoc
mfkrause 2e72e5e
docs(api): tag provider/platform-specific surface with TSDoc tags
mfkrause 25ce467
feat(docs): render provider/platform badges from TSDoc tags
mfkrause 3b7d3d0
feat(docs): add rich static landing page
mfkrause 4856676
feat(docs): wire favicon
mfkrause 0dd86a9
feat(docs): add sitemap, robots, and shared site config
mfkrause 2c0201c
feat(docs): add legacy redirects, Netlify config, and README
mfkrause 92fd0b1
chore(docs): update lockfile for Fumadocs migration
mfkrause 6a3f223
fix(docs): add header docs link, flatten API sidebar for mobile expan…
mfkrause 140a4c1
feat(docs): use package-manager install tabs (npm/pnpm/yarn/bun)
mfkrause 4ec8d68
docs: expand intro, deslop
mfkrause 9ac934e
style(docs): formatting improvements
mfkrause 9ed4f63
docs: add quick start
mfkrause 3782095
fix(docs): minor fixes
mfkrause File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| v20 | ||
| v24 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,27 @@ | ||
| # Dependencies | ||
| # deps | ||
| /node_modules | ||
|
|
||
| # Production | ||
| /build | ||
| # generated content | ||
| .source | ||
| content/docs/api | ||
|
|
||
| # Generated files | ||
| .docusaurus | ||
| .cache-loader | ||
| # test & build | ||
| /coverage | ||
| /.next/ | ||
| /out/ | ||
| /build | ||
| *.tsbuildinfo | ||
|
|
||
| # Misc | ||
| # misc | ||
| .DS_Store | ||
| .env.local | ||
| .env.development.local | ||
| .env.test.local | ||
| .env.production.local | ||
|
|
||
| *.pem | ||
| /.pnp | ||
| .pnp.js | ||
| npm-debug.log* | ||
| pnpm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
|
|
||
| # others | ||
| .env*.local | ||
| .vercel | ||
| next-env.d.ts |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,41 +1,46 @@ | ||
| # Website | ||
| # React Native Cloud Storage Documentation | ||
|
|
||
| This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. | ||
| The documentation site for [`react-native-cloud-storage`](https://github.com/kuatsu/react-native-cloud-storage), | ||
| built with [Fumadocs](https://fumadocs.dev) on Next.js. Deployed to | ||
| [react-native-cloud-storage.oss.kuatsu.de](https://react-native-cloud-storage.oss.kuatsu.de). | ||
|
|
||
| ### Installation | ||
| ## Structure | ||
|
|
||
| ```sh | ||
| $ pnpm install | ||
| ``` | ||
| - `content/docs/**` — authored MDX (installation, guides, example). | ||
| - `content/docs/api/**` — **generated** API reference (TypeDoc → Markdown). Git-ignored; do not edit by | ||
| hand. Regenerate with `pnpm docs:api`. | ||
| - `app/(home)` — landing page. `app/docs` — docs renderer. `lib/`, `config/`, `scripts/` — the | ||
| TypeDoc-to-Fumadocs pipeline and provider/platform badge machinery. | ||
|
|
||
| ## Development | ||
|
|
||
| ### Local Development | ||
| From the repo root (preferred, so workspace dependencies resolve): | ||
|
|
||
| ```sh | ||
| $ pnpm start | ||
| pnpm --filter react-native-cloud-storage-docs dev | ||
| ``` | ||
|
|
||
| This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. | ||
|
|
||
| ### Build | ||
| Or from this directory: | ||
|
|
||
| ```sh | ||
| $ pnpm build | ||
| pnpm dev # generate API reference, then start the dev server | ||
| pnpm docs:api # (re)generate content/docs/api from the library's TSDoc | ||
| pnpm build # production build | ||
| pnpm typecheck # generate API + types, then tsc --noEmit | ||
| ``` | ||
|
|
||
| This command generates static content into the `build` directory and can be served using any static contents hosting service. | ||
|
|
||
| ### Deployment | ||
| `dev`, `build`, and `typecheck` run `pnpm docs:api` first, so the generated API reference is always in | ||
| sync with `packages/react-native-cloud-storage/src`. | ||
|
|
||
| Using SSH: | ||
| ## API reference & badges | ||
|
|
||
| ```sh | ||
| $ USE_SSH=true pnpm deploy | ||
| ``` | ||
|
|
||
| Not using SSH: | ||
| The API reference is generated from the library's TypeScript and TSDoc by TypeDoc | ||
| (`typedoc.config.mts` + `scripts/typedoc-frontmatter.mts`). Provider/platform badges come from | ||
| additive `@platform` / `@provider` TSDoc tags in the library source; never edit the generated MDX. | ||
|
|
||
| ```sh | ||
| $ GIT_USER=<Your GitHub username> pnpm deploy | ||
| ``` | ||
| ## Deployment | ||
|
|
||
| If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. | ||
| Deployed on Netlify. Configuration lives in `netlify.toml` (base directory `apps/docs`, build command | ||
| `pnpm build`, publish directory `.next`, `@netlify/plugin-nextjs`). Netlify installs workspace | ||
| dependencies from the repo-root pnpm lockfile. If the site is instead configured through the Netlify | ||
| UI (as for other Kuatsu OSS sites), mirror those same values there. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| import { HomeLayout } from 'fumadocs-ui/layouts/home'; | ||
| import { baseOptions } from '@/lib/layout.shared'; | ||
|
|
||
| export default function Layout({ children }: LayoutProps<'/'>) { | ||
| return <HomeLayout {...baseOptions()}>{children}</HomeLayout>; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,149 @@ | ||
| import type { ReactNode } from 'react'; | ||
| import Link from 'next/link'; | ||
| import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock'; | ||
| import { ArrowRight, Cloud, FolderTree, Github, Layers, Puzzle, Webhook } from 'lucide-react'; | ||
| import { gitConfig } from '@/lib/layout.shared'; | ||
|
|
||
| const githubUrl = `https://github.com/${gitConfig.user}/${gitConfig.repo}`; | ||
|
|
||
| function InlineCode({ children }: { children: ReactNode }) { | ||
| return ( | ||
| <code className="rounded-md border border-fd-border bg-fd-muted px-1 py-0.5 font-mono text-[0.85em]"> | ||
| {children} | ||
| </code> | ||
| ); | ||
| } | ||
|
|
||
| const codeSample = `import { CloudStorage } from 'react-native-cloud-storage'; | ||
|
|
||
| // Write a file to the cloud... | ||
| await CloudStorage.writeFile('/data.json', data.toString()); | ||
|
|
||
| // ... and read it back! | ||
| const data = await CloudStorage.readFile('/data.json');`; | ||
|
|
||
| const features: { icon: typeof FolderTree; title: string; description: ReactNode }[] = [ | ||
| { | ||
| icon: FolderTree, | ||
| title: 'fs-like API', | ||
| description: ( | ||
| <> | ||
| Read, write, stat, and list files with an API that follows Node's <InlineCode>fs</InlineCode> conventions. | ||
| </> | ||
| ), | ||
| }, | ||
| { | ||
| icon: Cloud, | ||
| title: 'iCloud & Google Drive', | ||
| description: 'One API, two providers. Use the default platform backend, or pick your own.', | ||
| }, | ||
| { | ||
| icon: Webhook, | ||
| title: 'React hooks', | ||
| description: ( | ||
| <> | ||
| <InlineCode>useCloudFile</InlineCode> and <InlineCode>useIsCloudAvailable</InlineCode> keep your UI in sync with | ||
| cloud state. | ||
| </> | ||
| ), | ||
| }, | ||
| { | ||
| icon: Puzzle, | ||
| title: 'Expo config plugin', | ||
| description: 'Configure native capabilities automatically in Expo projects.', | ||
| }, | ||
| ]; | ||
|
|
||
| const providers = [ | ||
| { | ||
| name: 'iCloud (iOS only)', | ||
| scope: 'Backed by a native CloudKit module.', | ||
| }, | ||
| { | ||
| name: 'Google Drive', | ||
| scope: 'Backed by the Drive REST API using an access token.', | ||
| }, | ||
| ]; | ||
|
|
||
| export default function HomePage() { | ||
| return ( | ||
| <main className="mx-auto flex w-full max-w-6xl flex-col gap-12 px-4 py-10 md:py-16"> | ||
| <section className="grid items-center gap-8 rounded-3xl border border-fd-border bg-linear-to-br from-fd-primary/15 via-fd-background to-fd-background p-6 md:grid-cols-2 md:p-10"> | ||
| <div className="flex flex-col items-start gap-5"> | ||
| <p className="inline-flex items-center gap-2 rounded-full bg-fd-primary/12 px-3 py-1 text-sm font-medium text-fd-primary"> | ||
| <Cloud className="size-4" /> | ||
| React Native Cloud Storage | ||
| </p> | ||
| <h1 className="text-4xl font-semibold tracking-tight md:text-5xl"> | ||
| iCloud and Google Drive for | ||
| <span className="text-fd-primary"> React Native.</span> | ||
| </h1> | ||
| <p className="max-w-xl text-fd-muted-foreground md:text-lg"> | ||
| Use iCloud and Google Drive as file storage in your React Native app, with a single fs-like API, React | ||
| hooks, and an Expo config plugin. | ||
| </p> | ||
| <div className="flex flex-wrap items-center gap-3"> | ||
| <Link | ||
| href="/docs" | ||
| className="inline-flex items-center gap-2 rounded-xl bg-fd-primary px-5 py-2.5 text-base font-medium text-fd-primary-foreground transition-opacity hover:opacity-90"> | ||
| Get started | ||
| <ArrowRight className="size-4" /> | ||
| </Link> | ||
| <a | ||
| href={githubUrl} | ||
| rel="noreferrer noopener" | ||
| target="_blank" | ||
| className="inline-flex items-center gap-2 rounded-xl border border-fd-border bg-fd-card px-5 py-2.5 text-base font-medium transition-colors hover:bg-fd-accent"> | ||
| <Github className="size-4" /> | ||
| GitHub | ||
| </a> | ||
| </div> | ||
| </div> | ||
| <div className="min-w-0 text-sm"> | ||
| <DynamicCodeBlock lang="ts" code={codeSample} /> | ||
| </div> | ||
| </section> | ||
|
|
||
| <section className="grid gap-4 md:grid-cols-2"> | ||
| {features.map((feature) => ( | ||
| <article key={feature.title} className="rounded-2xl border border-fd-border bg-fd-card p-5"> | ||
| <p className="mb-2 inline-flex items-center gap-2 text-base font-medium"> | ||
| <feature.icon className="size-5 text-fd-primary" /> | ||
| {feature.title} | ||
| </p> | ||
| <p className="text-sm text-fd-muted-foreground">{feature.description}</p> | ||
| </article> | ||
| ))} | ||
| </section> | ||
|
|
||
| <section className="grid gap-4 md:grid-cols-2"> | ||
| {providers.map((provider) => ( | ||
| <article | ||
| key={provider.name} | ||
| className="flex items-start gap-4 rounded-2xl border border-fd-border bg-fd-card p-5"> | ||
| <span className="flex size-10 shrink-0 items-center justify-center rounded-xl bg-fd-primary/10 text-fd-primary"> | ||
| <Layers className="size-5" /> | ||
| </span> | ||
| <div> | ||
| <p className="text-base font-medium">{provider.name}</p> | ||
| <p className="text-sm text-fd-muted-foreground">{provider.scope}</p> | ||
| </div> | ||
| </article> | ||
| ))} | ||
| </section> | ||
|
|
||
| <section className="flex flex-col items-center gap-4 rounded-3xl border border-fd-border bg-fd-card p-8 text-center"> | ||
| <h2 className="text-2xl font-semibold tracking-tight">Ready to back up your app's files?</h2> | ||
| <p className="max-w-xl text-fd-muted-foreground"> | ||
| Install the library, follow the platform setup, and start reading and writing cloud files in minutes. | ||
| </p> | ||
| <Link | ||
| href="/docs" | ||
| className="inline-flex items-center gap-2 rounded-xl bg-fd-primary px-5 py-2.5 text-base font-medium text-fd-primary-foreground transition-opacity hover:opacity-90"> | ||
| Read the docs | ||
| <ArrowRight className="size-4" /> | ||
| </Link> | ||
| </section> | ||
| </main> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { source } from '@/lib/source'; | ||
| import { createFromSource } from 'fumadocs-core/search/server'; | ||
|
|
||
| export const { GET } = createFromSource(source, { | ||
| // https://docs.orama.com/docs/orama-js/supported-languages | ||
| language: 'english', | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| import { getPageImage, source } from '@/lib/source'; | ||
| import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/layouts/docs/page'; | ||
| import { notFound } from 'next/navigation'; | ||
| import { getMDXComponents } from '@/mdx-components'; | ||
| import type { Metadata } from 'next'; | ||
| import { createRelativeLink } from 'fumadocs-ui/mdx'; | ||
| import { LLMCopyButton, ViewOptions } from '@/components/ai/page-actions'; | ||
| import { BadgePills } from '@/components/badges/pills'; | ||
| import { readBadgesFromPageData, readTocBadgesFromPageData } from '@/lib/badges'; | ||
| import { gitConfig } from '@/lib/layout.shared'; | ||
|
|
||
| export default async function Page(props: PageProps<'/docs/[[...slug]]'>) { | ||
| const params = await props.params; | ||
| const page = source.getPage(params.slug); | ||
| if (!page) notFound(); | ||
|
|
||
| const MDX = page.data.body; | ||
| const badges = readBadgesFromPageData(page.data); | ||
| const tocBadges = readTocBadgesFromPageData(page.data); | ||
| const isApiPage = page.path.startsWith('api/'); | ||
|
|
||
| // API pages are generated from the library source, so link "Open in GitHub" to the package source | ||
| // rather than the (gitignored) generated MDX file. | ||
| const githubUrl = isApiPage | ||
| ? `https://github.com/${gitConfig.user}/${gitConfig.repo}/tree/${gitConfig.branch}/packages/react-native-cloud-storage/src` | ||
| : `https://github.com/${gitConfig.user}/${gitConfig.repo}/blob/${gitConfig.branch}/apps/docs/content/docs/${page.path}`; | ||
|
|
||
| return ( | ||
| <DocsPage toc={page.data.toc} full={page.data.full}> | ||
| <DocsTitle>{page.data.title}</DocsTitle> | ||
| <BadgePills badges={badges} /> | ||
| <DocsDescription className="mb-0">{page.data.description}</DocsDescription> | ||
| <div className="flex flex-row gap-2 items-center border-b pb-6"> | ||
| <LLMCopyButton markdownUrl={`${page.url}.mdx`} /> | ||
| <ViewOptions markdownUrl={`${page.url}.mdx`} githubUrl={githubUrl} /> | ||
| </div> | ||
| <DocsBody className={isApiPage ? 'api-reference-body' : undefined}> | ||
| <MDX | ||
| components={getMDXComponents( | ||
| { | ||
| a: createRelativeLink(source, page), | ||
| }, | ||
| { tocBadges } | ||
| )} | ||
| /> | ||
| </DocsBody> | ||
| </DocsPage> | ||
| ); | ||
| } | ||
|
|
||
| export async function generateStaticParams() { | ||
| return source.generateParams(); | ||
| } | ||
|
|
||
| export async function generateMetadata(props: PageProps<'/docs/[[...slug]]'>): Promise<Metadata> { | ||
| const params = await props.params; | ||
| const page = source.getPage(params.slug); | ||
| if (!page) notFound(); | ||
|
|
||
| return { | ||
| title: page.data.title, | ||
| description: page.data.description, | ||
| openGraph: { | ||
| images: getPageImage(page).url, | ||
| }, | ||
| }; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { source } from '@/lib/source'; | ||
| import { DocsLayout } from 'fumadocs-ui/layouts/docs'; | ||
| import { baseOptions } from '@/lib/layout.shared'; | ||
|
|
||
| export default function Layout({ children }: LayoutProps<'/docs'>) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This file repeats the undefined 🤖 Prompt for AI Agents |
||
| return ( | ||
| <DocsLayout tree={source.getPageTree()} {...baseOptions()}> | ||
| {children} | ||
| </DocsLayout> | ||
| ); | ||
| } | ||
File renamed without changes.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LayoutProps<'/'>undefined — same cross-file TypeScript error as root layout.This file also uses the undefined
LayoutProps<'/'>type. Once the type is defined and imported globally (or in a layout types file), apply it consistently across all layout files:apps/docs/app/layout.tsx,apps/docs/app/(home)/layout.tsx, andapps/docs/app/docs/layout.tsx.🤖 Prompt for AI Agents