ernestdefoe / gh-readme
Paste a GitHub repo URL into the Flarum composer and the URL is auto-replaced with the rendered README markdown.
Package info
github.com/ernestdefoe/gh-readme
Type:flarum-extension
pkg:composer/ernestdefoe/gh-readme
Requires
- php: ^8.2
- flarum/core: ^2.0
- guzzlehttp/guzzle: ^7.0
Suggests
- flarum/markdown: Required for the inserted README markdown to render with headings, lists, code blocks, etc. — without it, the raw markdown still ends up in the post but renders as plain text.
README
Paste a GitHub repo URL into the Flarum composer and the URL is auto-replaced with the rendered README markdown.
How it works
- User pastes
https://github.com/owner/repointo any composer (new discussion, reply, edit, private message). - The frontend recognizes it as a GitHub repo root URL and intercepts the paste.
- It calls
POST /api/gh-readme/fetchon the Flarum backend. - The backend fetches
https://api.github.com/repos/{owner}/{repo}/readme, decodes the base64 payload, rewrites relative image / link / anchor URLs against the repo's HEAD branch onraw.githubusercontent.com, and returns the processed markdown. - The frontend replaces the URL in the composer with the README markdown. The user can edit freely from there.
Subsequent pastes of the same repo are served from a 10-minute server-side cache so a popular forum doesn't burn GitHub's rate limit.
Works with both composer types
| Composer | Behavior |
|---|---|
Default Flarum (textarea + flarum/markdown) |
URL replaced inline by the markdown source. The post renders as formatted markdown at display time. A visible italic "Loading…" marker shows in the textarea during the fetch. |
fof/rich-text (Tiptap WYSIWYG) |
URL replaced by rich nodes — headings, paragraphs, lists, code blocks, blockquotes, images all appear formatted in the composer immediately. A toast notification shows during the fetch (no inline marker — finding a specific text node inside a ProseMirror document is brittle). |
Detection is automatic via the presence of editor.editor on the active driver. No setting needed.
Install
composer require ernestdefoe/gh-readme php flarum cache:clear
Then enable in Admin → Extensions → GitHub README Paste.
flarum/markdown is a suggest dep — without it the inserted markdown ends up in the post but renders as plain text rather than formatted headings/lists/code blocks.
Configure
Admin → Extensions → GitHub README Paste:
- GitHub Personal Access Token (optional) — raises GitHub's API rate limit from 60/hour-per-IP (unauth) to 5000/hour. No scopes required for public repos.
- Cache duration (minutes) — how long the server caches each README before refetching. Default 10. Clamped 1–60.
URL shapes accepted
| URL | Behavior |
|---|---|
https://github.com/owner/repo |
✅ expanded |
https://github.com/owner/repo/ |
✅ expanded |
https://github.com/owner/repo.git |
✅ expanded (strips .git) |
https://www.github.com/owner/repo |
✅ expanded |
https://github.com/owner/repo/tree/main |
❌ left as-is (use the root URL) |
https://github.com/owner/repo/blob/main/file.md |
❌ left as-is (file links, not repos) |
http://github.com/owner/repo |
❌ rejected (must be https) |
https://gitlab.com/owner/repo |
❌ not GitHub |
Security notes
- Strict URL allowlist (
github.comhost only). - Owner/repo regex-allowlisted to GitHub's own charset.
- The backend never fetches the user-supplied URL directly — it constructs the API call from validated owner/repo segments. SSRF surface is the GitHub API host only.
- Response body capped at 2 MB.
- 10s connect + 15s total request timeout.
- TLS verification on.
- Endpoint requires an authenticated Flarum actor; throttled by Flarum's standard per-actor API throttler.
License
MIT — see LICENSE.