UI: Recommend using custom button/link instead for edit on GitHub button

This commit is contained in:
Fuma Nama
2025-05-03 17:13:06 +08:00
parent 7b89faa74b
commit b433d93946
12 changed files with 65 additions and 142 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-ui': patch
---
Recommend using custom button/link instead for edit on GitHub button
@@ -1,6 +0,0 @@
---
title: Changelog
description: Updates of Fumadocs
---
<include cwd>../../packages/ui/CHANGELOG.md</include>
@@ -1,4 +0,0 @@
{
"description": "Changelogs of Fumadocs",
"root": true
}
+1 -1
View File
@@ -1,3 +1,3 @@
{
"pages": ["ui", "headless", "mdx", "cli", "changelogs", "openapi"]
"pages": ["ui", "headless", "mdx", "cli", "openapi"]
}
+25 -40
View File
@@ -38,7 +38,26 @@ It applies the [Typography](/docs/ui/theme#typography) styles, wrap your content
import { DocsBody } from 'fumadocs-ui/page';
<DocsBody>
<h1>This heading looks good!</h1>
<h2>This heading looks good!</h2>
</DocsBody>;
```
### Edit on GitHub
You can also add your own component.
```tsx
import { DocsBody } from 'fumadocs-ui/page';
<DocsBody>
<a
href={`https://github.com/fuma-nama/fumadocs/blob/main/${page.file.path}`}
rel="noreferrer noopener"
target="_blank"
className="w-fit border rounded-xl p-2 font-medium text-sm text-fd-secondary-foreground bg-fd-secondary transition-colors hover:text-fd-accent-foreground hover:bg-fd-accent"
>
Edit on GitHub
</a>
</DocsBody>;
```
@@ -68,12 +87,14 @@ import { DocsPage } from 'fumadocs-ui/page';
<DocsPage toc={headings}>...</DocsPage>;
```
Customise or disable TOC from your documentation with the `tableOfContent` option.
You can customise or disable it with the `tableOfContent` option, or with `tableOfContentPopover` on smaller devices.
```tsx
import { DocsPage } from 'fumadocs-ui/page';
<DocsPage tableOfContent={options}>...</DocsPage>;
<DocsPage tableOfContent={options} tableOfContentPopover={options}>
...
</DocsPage>;
```
<AutoTypeTable path="./content/docs/ui/props.ts" name="TOCProps" />
@@ -94,19 +115,6 @@ import { DocsPage } from 'fumadocs-ui/page';
</DocsPage>;
```
#### Popover Mode
On smaller devices, it is shown on a popover instead.
Customise it with the `tableOfContentPopover` option.
```tsx
import { DocsPage } from 'fumadocs-ui/page';
<DocsPage tableOfContentPopover={options}>...</DocsPage>;
```
<AutoTypeTable path="./content/docs/ui/props.ts" name="TOCPopoverProps" />
### Last Updated Time
Display last updated time of the page.
@@ -137,30 +145,7 @@ const time = await getGithubLastEdit({
<DocsPage lastUpdate={new Date(time)} />;
```
<Callout type='info' title='Note'>
You can also specify the last updated time of documents (e.g. using frontmatter).
Don't forget to [update the schema type](/docs/mdx/collections#schema) on Fumadocs MDX first.
</Callout>
### Edit on GitHub
Add "Edit on GitHub" button to the page.
```tsx
import { DocsPage } from 'fumadocs-ui/page';
<DocsPage
editOnGithub={{
owner: 'fuma-nama',
repo: 'fumadocs',
sha: 'main',
// file path, make sure it's valid
path: `content/docs/${page.file.path}`,
}}
/>;
```
Or you may specify the updated time in [frontmatter](/docs/mdx/collections#schema).
### Footer
@@ -14,8 +14,6 @@ const client = algo(appId, apiKey);
const index = client.initIndex(indexName);
export default function CustomSearchDialog(
props: SharedProps,
): React.ReactElement {
export default function CustomSearchDialog(props: SharedProps) {
return <SearchDialog index={index} {...props} showAlgolia />;
}
+1 -13
View File
@@ -177,19 +177,7 @@ For the setup guide, see [Integrate Algolia Search](/docs/headless/search/algoli
While generally we recommend building your own search with their client-side
SDK, you can also plug the built-in dialog interface.
```tsx title="components/search.tsx"
'use client';
import algo from 'algoliasearch/lite';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
import SearchDialog from 'fumadocs-ui/components/dialog/search-algolia';
const client = algo('appId', 'apiKey');
const index = client.initIndex('indexName');
export default function CustomSearchDialog(props: SharedProps) {
return <SearchDialog index={index} {...props} />;
}
```
<include meta='title="components/search.tsx"'>./search-algolia.tsx</include>
1. Replace `appId`, `apiKey` and `indexName` with your desired values.
-43
View File
@@ -1,43 +0,0 @@
import * as fs from 'node:fs/promises';
import fg from 'fast-glob';
import matter from 'gray-matter';
import { remark } from 'remark';
import remarkGfm from 'remark-gfm';
import remarkStringify from 'remark-stringify';
import remarkMdx from 'remark-mdx';
import { remarkInclude } from 'fumadocs-mdx/config';
export const revalidate = false;
const processor = remark()
.use(remarkMdx)
// https://fumadocs.dev/docs/mdx/include
.use(remarkInclude)
// gfm styles
.use(remarkGfm)
// .use(your remark plugins)
.use(remarkStringify); // to string
export async function GET() {
// all scanned content
const files = await fg(['./content/docs/**/*.mdx']);
const scan = files.map(async (file) => {
const fileContent = await fs.readFile(file);
const { content, data } = matter(fileContent.toString());
const processed = await processor.process({
path: file,
value: content,
});
return `file: ${file}
meta: ${JSON.stringify(data, null, 2)}
${processed}`;
});
const scanned = await Promise.all(scan);
return new Response(scanned.join('\n\n'));
}
+1 -1
View File
@@ -48,7 +48,6 @@
"remark-math": "^6.0.0",
"remark-mdx": "^3.1.0",
"remark-rehype": "^11.1.2",
"remark-stringify": "^11.0.0",
"scroll-into-view-if-needed": "^3.1.0",
"shiki": "^3.3.0",
"tailwind-merge": "^3.2.0",
@@ -66,6 +65,7 @@
"@types/node": "22.15.3",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.3",
"algoliasearch": "4.24.0",
"eslint-config-custom": "workspace:*",
"fast-glob": "^3.3.3",
"gray-matter": "^4.0.3",
+1 -1
View File
@@ -13,7 +13,7 @@ export const buttonVariants = cva(
'border bg-fd-secondary text-fd-secondary-foreground hover:bg-fd-accent hover:text-fd-accent-foreground',
},
size: {
sm: 'gap-1 p-1 text-xs',
sm: 'gap-1 px-2 py-1.5 text-xs',
icon: 'p-1.5 [&_svg]:size-5',
'icon-sm': 'p-1.5 [&_svg]:size-4.5',
},
+24 -24
View File
@@ -1,24 +1,25 @@
import type { TableOfContents } from 'fumadocs-core/server';
import {
type AnchorHTMLAttributes,
type ComponentProps,
forwardRef,
type HTMLAttributes,
type ReactNode,
} from 'react';
import { type AnchorProviderProps, AnchorProvider } from 'fumadocs-core/toc';
import { AnchorProvider, type AnchorProviderProps } from 'fumadocs-core/toc';
import { slot } from '@/layouts/shared';
import { cn } from './utils/cn';
import {
Breadcrumb,
type BreadcrumbProps,
Footer,
type FooterProps,
LastUpdate,
TocPopover,
Breadcrumb,
type BreadcrumbProps,
PageBody,
PageArticle,
TocPopoverTrigger,
PageBody,
TocPopover,
TocPopoverContent,
TocPopoverTrigger,
} from './page-client';
import {
Toc,
@@ -114,6 +115,7 @@ export interface DocsPageProps {
export function DocsPage({
toc = [],
full = false,
editOnGithub,
tableOfContentPopover: {
enabled: tocPopoverEnabled,
component: tocPopoverReplace,
@@ -183,12 +185,14 @@ export function DocsPage({
{props.children}
<div role="none" className="flex-1" />
<div className="flex flex-row flex-wrap items-center justify-between gap-4 empty:hidden">
{props.editOnGithub ? (
<EditOnGitHub {...props.editOnGithub} />
) : null}
{props.lastUpdate ? (
{editOnGithub && (
<EditOnGitHub
href={`https://github.com/${editOnGithub.owner}/${editOnGithub.repo}/blob/${editOnGithub.sha}/${editOnGithub.path.startsWith('/') ? editOnGithub.path.slice(1) : editOnGithub.path}`}
/>
)}
{props.lastUpdate && (
<LastUpdate date={new Date(props.lastUpdate)} />
) : null}
)}
</div>
{slot(props.footer, <Footer items={props.footer?.items} />)}
</PageArticle>
@@ -219,31 +223,27 @@ export function DocsPage({
);
}
function EditOnGitHub({
owner,
repo,
sha,
path,
...props
}: EditOnGitHubOptions) {
const href = `https://github.com/${owner}/${repo}/blob/${sha}/${path.startsWith('/') ? path.slice(1) : path}`;
export function EditOnGitHub(props: ComponentProps<'a'>) {
return (
<a
href={href}
target="_blank"
rel="noreferrer noopener"
{...props}
className={cn(
buttonVariants({
color: 'secondary',
className: 'gap-1.5 text-fd-muted-foreground',
size: 'sm',
className: 'gap-1.5 not-prose',
}),
props.className,
)}
>
<Edit className="size-3.5" />
<I18nLabel label="editOnGithub" />
{props.children ?? (
<>
<Edit className="size-3.5" />
<I18nLabel label="editOnGithub" />
</>
)}
</a>
);
}
+6 -6
View File
@@ -164,9 +164,6 @@ importers:
remark-rehype:
specifier: ^11.1.2
version: 11.1.2
remark-stringify:
specifier: ^11.0.0
version: 11.0.0
scroll-into-view-if-needed:
specifier: ^3.1.0
version: 3.1.0
@@ -213,6 +210,9 @@ importers:
'@types/react-dom':
specifier: ^19.1.3
version: 19.1.3(@types/[email protected])
algoliasearch:
specifier: 4.24.0
version: 4.24.0
eslint-config-custom:
specifier: workspace:*
version: link:../../packages/eslint-config-custom
@@ -276,7 +276,7 @@ importers:
version: 0.2.2(@content-collections/[email protected]([email protected]))([email protected])([email protected]([email protected]))([email protected])
'@content-collections/next':
specifier: ^0.2.6
version: 0.2.6(@content-collections/[email protected]([email protected]))([email protected](@opentelemetry/[email protected])([email protected]([email protected]))([email protected]))
version: 0.2.6(@content-collections/[email protected]([email protected]))([email protected](@babel/[email protected])(@opentelemetry/[email protected])([email protected])([email protected]([email protected]))([email protected]))
'@types/mdx':
specifier: ^2.0.13
version: 2.0.13
@@ -871,7 +871,7 @@ importers:
version: 0.2.2(@content-collections/[email protected]([email protected]))([email protected])([email protected]([email protected]))([email protected])
'@content-collections/next':
specifier: ^0.2.6
version: 0.2.6(@content-collections/[email protected]([email protected]))([email protected](@opentelemetry/[email protected])([email protected]([email protected]))([email protected]))
version: 0.2.6(@content-collections/[email protected]([email protected]))([email protected](@babel/[email protected])(@opentelemetry/[email protected])([email protected])([email protected]([email protected]))([email protected]))
'@react-router/dev':
specifier: ^7.5.3
version: 7.5.3(@react-router/[email protected]([email protected]([email protected]([email protected]))([email protected]))([email protected]))(@types/[email protected])([email protected])([email protected])([email protected])([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))([email protected])
@@ -10980,7 +10980,7 @@ snapshots:
- acorn
- supports-color
'@content-collections/[email protected](@content-collections/[email protected]([email protected]))([email protected](@opentelemetry/[email protected])([email protected]([email protected]))([email protected]))':
'@content-collections/[email protected](@content-collections/[email protected]([email protected]))([email protected](@babel/[email protected])(@opentelemetry/[email protected])([email protected])([email protected]([email protected]))([email protected]))':
dependencies:
'@content-collections/core': 0.8.2([email protected])
'@content-collections/integrations': 0.2.1(@content-collections/[email protected]([email protected]))