反馈
接收用户的反馈
概述
反馈对于了解读者所想至关重要,并帮助您进一步改进文档内容。
安装
Fumadocs CLI
npx @fumadocs/cli@latest add feedbackShadcn CLI
npx shadcn@latest add https://fumadocs.dev/r/feedback.json使用
现在将 <Feedback /> 组件添加到您的文档页面:
import { DocsPage } from 'fumadocs-ui/page';
import { Feedback } from '@/components/feedback';
import posthog from 'posthog-js';
export default async function Page() {
return (
<DocsPage>
{/* 在页面底部 */}
<Feedback
onRateAction={async (url, feedback) => {
'use server';
await posthog.capture('on_rate_docs', feedback);
}}
/>
</DocsPage>
);
}onRateAction:用户提交反馈时触发。
您可以指定一个服务器操作,或任何函数(在客户端组件中)。例如,将用户反馈报告为 PostHog 上的 on_rate_docs 事件。
与 GitHub Discussion 集成
要将您的反馈报告到 GitHub Discussion,请制作一个自定义的 onRateAction。
您可以复制此服务器操作作为起点:
import { App, Octokit } from 'octokit';
import type { ActionResponse, Feedback } from '@/components/feedback';
export const repo = 'fumadocs';
export const owner = 'fuma-nama';
export const DocsCategory = 'Docs Feedback';
let instance: Octokit | undefined;
async function getOctokit(): Promise<Octokit> {
if (instance) return instance;
const appId = process.env.GITHUB_APP_ID;
const privateKey = process.env.GITHUB_APP_PRIVATE_KEY;
if (!appId || !privateKey) {
throw new Error(
'No GitHub keys provided for Github app, docs feedback feature will not work.',
);
}
const app = new App({
appId,
privateKey,
});
const { data } = await app.octokit.request(
'GET /repos/{owner}/{repo}/installation',
{
owner,
repo,
headers: {
'X-GitHub-Api-Version': '2022-11-28',
},
},
);
instance = await app.getInstallationOctokit(data.id);
return instance;
}
interface RepositoryInfo {
id: string;
discussionCategories: {
nodes: {
id: string;
name: string;
}[];
};
}
let cachedDestination: RepositoryInfo | undefined;
async function getFeedbackDestination() {
if (cachedDestination) return cachedDestination;
const octokit = await getOctokit();
const {
repository,
}: {
repository: RepositoryInfo;
} = await octokit.graphql(`
query {
repository(owner: "${owner}", name: "${repo}") {
id
discussionCategories(first: 25) {
nodes { id name }
}
}
}
`);
return (cachedDestination = repository);
}
export async function onRateAction(
url: string,
feedback: Feedback,
): Promise<ActionResponse> {
'use server';
const octokit = await getOctokit();
const destination = await getFeedbackDestination();
if (!octokit || !destination)
throw new Error('GitHub comment integration is not configured.');
const category = destination.discussionCategories.nodes.find(
(category) => category.name === DocsCategory,
);
if (!category)
throw new Error(
`Please create a "${DocsCategory}" category in GitHub Discussion`,
);
const title = `Feedback for ${url}`;
const body = `[${feedback.opinion}] ${feedback.message}\n\n> Forwarded from user feedback.`;
let {
search: {
nodes: [discussion],
},
}: {
search: {
nodes: { id: string; url: string }[];
};
} = await octokit.graphql(`
query {
search(type: DISCUSSION, query: ${JSON.stringify(`${title} in:title repo:${owner}/${repo} author:@me`)}, first: 1) {
nodes {
... on Discussion { id, url }
}
}
}`);
if (discussion) {
await octokit.graphql(`
mutation {
addDiscussionComment(input: { body: ${JSON.stringify(body)}, discussionId: "${discussion.id}" }) {
comment { id }
}
}`);
} else {
const result: {
discussion: { id: string; url: string };
} = await octokit.graphql(`
mutation {
createDiscussion(input: { repositoryId: "${destination.id}", categoryId: "${category!.id}", body: ${JSON.stringify(body)}, title: ${JSON.stringify(title)} }) {
discussion { id, url }
}
}`);
discussion = result.discussion;
}
return {
githubUrl: discussion.url,
};
}- 创建您自己的 GitHub App 并获取其应用 ID 和私钥。
- 填写必需的环境变量。
- 替换常量,如
owner、repo和DocsCategory。
How is this guide?
Last updated on
