Skip to content

vitepress-plugin-report-issue

Ctrl+Enter on any VitePress page opens a modal that packs the URL, the current page title and the selected fragment into a pre-filled /<owner>/<repo>/issues/new?title=...&body=...&labels=... link on Forgejo/Gitea. The user then presses "Submit" inside the tracker UI they are already logged into.

No backend, no tokens, no CORS: the plugin only assembles a URL and hands it to the browser. Everything a documentation bug reporter needs is to read the page, highlight the problematic snippet and press the shortcut.

Installation

bash
pnpm add @ampernic/vitepress-plugin-report-issue

Packages in the @ampernic scope are published to the Forgejo registry. When installing outside of npm, add .npmrc to the project root:

@ampernic:registry=https://altlinux.space/api/packages/ampernic/npm/

Usage

Registered as a Vue plugin in enhanceApp; the dialog is mounted once in the layout.

ts
// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import { h } from 'vue'
import ReportIssuePlugin, { ReportIssueDialog } from '@ampernic/vitepress-plugin-report-issue'

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    app.use(ReportIssuePlugin, {
      repo: 'alt-docs/docs-vitepress',
      origin: 'https://altlinux.space',
      labels: ['documentation'],
      shortcut: 'ctrl-enter',
      locale: 'en',
    })
  },
  Layout: () => h(DefaultTheme.Layout, null, {
    'layout-top': () => h(ReportIssueDialog),
  }),
}

The plugin binds a global keydown handler and opens the modal on a matching shortcut. The same option, passed as a prop to <ReportIssueDialog>, overrides the plugin config: handy when a specific subsection needs to file into a different repository.

Through createSharedConfig in @ampernic/vitepress-theme-alt-docs the same options are wired via the reportIssue field.

Options

OptionTypeDefaultDescription
repostring--Required. owner/name slug of a Forgejo/Gitea repository
originstring'https://altlinux.space'Base of the Forgejo/Gitea instance
labelsstring[][]Labels attached to the issue through the query
shortcut'ctrl-enter' | 'meta-enter''ctrl-enter'Trigger shortcut. meta-enter is Cmd+Enter on macOS
localestringuseData().langOverrides the dialog UI language
fallbackLocalestring'en'Locale fallback when the current one has no translation
messagesPartial<Record<string, Partial<Messages>>>{}Point translations of specific strings per locale

Localization

ru and en are bundled. Extra locales are supplied via messages; the field keys live in Messages (every string a user can see). Adding German:

ts
app.use(ReportIssuePlugin, {
  repo: 'my-org/my-docs',
  messages: {
    de: {
      title: 'Dokumentationsfehler melden',
      submit: 'Bei Forgejo weiter',
    },
  },
})

Why URL, not POST

A URL pre-fill opens the issue creation form in the Forgejo UI where the user is already authenticated. No service token, no configured CORS, no custom rate limit. When the project grows to headless submission (a mobile app, an iframe embed), the same assembled URL can be pushed to /api/v1/repos/{owner}/{repo}/issues with a personal token.