Title: Markdown Editor Injection for Solid Pods (HackMD-style) · Issue #3 · JavaScriptSolidServer/podkey · GitHub
Open Graph Title: Markdown Editor Injection for Solid Pods (HackMD-style) · Issue #3 · JavaScriptSolidServer/podkey
X Title: Markdown Editor Injection for Solid Pods (HackMD-style) · Issue #3 · JavaScriptSolidServer/podkey
Description: Markdown Editor Injection for Solid Pods (HackMD-style) Overview Add content script functionality to detect markdown files on Solid pods and inject a live editor interface (similar to HackMD), allowing users to edit and save markdown fil...
Open Graph Description: Markdown Editor Injection for Solid Pods (HackMD-style) Overview Add content script functionality to detect markdown files on Solid pods and inject a live editor interface (similar to HackMD), allo...
X Description: Markdown Editor Injection for Solid Pods (HackMD-style) Overview Add content script functionality to detect markdown files on Solid pods and inject a live editor interface (similar to HackMD), allo...
Opengraph URL: https://github.com/JavaScriptSolidServer/podkey/issues/3
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Markdown Editor Injection for Solid Pods (HackMD-style)","articleBody":"# Markdown Editor Injection for Solid Pods (HackMD-style)\n\n## Overview\nAdd content script functionality to detect markdown files on Solid pods and inject a live editor interface (similar to HackMD), allowing users to edit and save markdown files directly in the browser with Nostr-signed authentication.\n\n## Problem Statement\nCurrently, editing markdown files in Solid pods requires:\n1. Downloading the file\n2. Editing locally\n3. Re-uploading\n4. Managing authentication separately\n\nUsers expect a seamless, in-browser editing experience like HackMD, Notion, or GitHub's markdown editor.\n\n## Proposed Solution\nInject a live markdown editor when users navigate to `.md` files on Solid pods, with:\n- ✍️ Syntax-highlighted editing\n- 👁️ Live preview pane\n- 💾 One-click save (authenticated via Nostr signature)\n- 🔒 Auto-authentication for trusted pods\n- ⚡ Works on ANY Solid pod\n\n## Technical Implementation\n\n### 1. Solid Pod Detection\n\nMultiple strategies for detecting Solid pods:\n\n#### Strategy A: HTTP Headers (Most Reliable)\n```javascript\n// In src/background.js\nconst solidPodCache = new Map();\n\nchrome.webRequest.onHeadersReceived.addListener(\n (details) =\u003e {\n const headers = details.responseHeaders;\n\n // Check for Solid-specific headers\n const isSolid = headers.some(h =\u003e\n h.name.toLowerCase() === 'wac-allow' || // Web Access Control\n h.name.toLowerCase() === 'updates-via' || // WebSocket updates\n (h.name.toLowerCase() === 'link' \u0026\u0026\n h.value.includes('ldp#Resource')) || // Linked Data Platform\n (h.name.toLowerCase() === 'x-powered-by' \u0026\u0026\n h.value.includes('JavaScriptSolidServer')) // JSS-specific\n );\n\n if (isSolid) {\n const origin = new URL(details.url).origin;\n solidPodCache.set(origin, {\n detected: Date.now(),\n headers: headers.filter(h =\u003e h.name.toLowerCase().includes('solid'))\n });\n\n // Notify content script\n chrome.tabs.sendMessage(details.tabId, {\n type: 'SOLID_POD_DETECTED',\n url: details.url,\n headers: headers\n });\n }\n },\n { urls: [\"\u003call_urls\u003e\"] },\n [\"responseHeaders\"]\n);\n\n// Message handler for cache queries\nchrome.runtime.onMessage.addListener((message, sender, sendResponse) =\u003e {\n if (message.type === 'CHECK_SOLID_CACHE') {\n const origin = new URL(message.url).origin;\n sendResponse(solidPodCache.get(origin));\n }\n});\n```\n\n#### Strategy B: Well-Known Endpoint (Standard)\n```javascript\n// In content script\nasync function checkWellKnownSolid(url) {\n const origin = new URL(url).origin;\n\n try {\n const response = await fetch(`${origin}/.well-known/solid`);\n if (response.ok) {\n const config = await response.json();\n // Config contains: storage, oidcIssuer, etc.\n return config;\n }\n } catch (e) {\n console.log('[Podkey] No .well-known/solid found');\n return null;\n }\n}\n```\n\n#### Strategy C: User Allowlist (Fast, Manual)\n```javascript\n// User-maintained list in chrome.storage\nconst DEFAULT_POD_PROVIDERS = [\n 'solidcommunity.net',\n 'solidweb.org',\n 'inrupt.net',\n 'pod.inrupt.com',\n 'localhost:8080'\n];\n\nasync function isKnownPodProvider(url) {\n const { podkey_known_providers = DEFAULT_POD_PROVIDERS } =\n await chrome.storage.local.get(['podkey_known_providers']);\n\n const hostname = new URL(url).hostname;\n return podkey_known_providers.some(provider =\u003e\n hostname.includes(provider)\n );\n}\n```\n\n#### Hybrid Detection (Recommended)\n```javascript\nasync function isSolidPod(url) {\n // 1. Check cache from webRequest (instant)\n const cached = await chrome.runtime.sendMessage({\n type: 'CHECK_SOLID_CACHE',\n url\n });\n if (cached) return cached;\n\n // 2. Check known providers (fast)\n if (await isKnownPodProvider(url)) return { detected: true, source: 'allowlist' };\n\n // 3. Check well-known (definitive but slower)\n const wellKnown = await checkWellKnownSolid(url);\n if (wellKnown) return { detected: true, source: 'well-known', config: wellKnown };\n\n // 4. Content detection (fallback)\n const hasDataBrowser = document.querySelector('script[src*=\"mashlib\"]') ||\n document.querySelector('script[src*=\"solid-ui\"]');\n if (hasDataBrowser) return { detected: true, source: 'content' };\n\n return null;\n}\n```\n\n### 2. Markdown Detection\n\n```javascript\n// src/content-markdown.js\nasync function isMarkdownFile(url) {\n // Check URL extension\n if (url.endsWith('.md') || url.endsWith('.markdown')) {\n return true;\n }\n\n // Check Content-Type header\n const contentType = document.contentType;\n if (contentType?.includes('text/markdown')) {\n return true;\n }\n\n // Check for pre-rendered markdown (some servers render to HTML)\n const preElement = document.querySelector('pre');\n if (preElement \u0026\u0026 preElement.textContent.match(/^#\\s+.+/m)) {\n return true;\n }\n\n return false;\n}\n```\n\n### 3. Editor Injection\n\n```javascript\n// src/content-markdown.js\nasync function injectMarkdownEditor() {\n const isSolid = await isSolidPod(window.location.href);\n if (!isSolid) return;\n\n const isMarkdown = await isMarkdownFile(window.location.href);\n if (!isMarkdown) return;\n\n // Fetch current content\n const response = await fetch(window.location.href);\n const content = await response.text();\n\n // Replace page with editor\n document.body.innerHTML = '';\n document.body.className = 'podkey-markdown-editor';\n\n const editorContainer = document.createElement('div');\n editorContainer.id = 'podkey-editor-container';\n editorContainer.innerHTML = `\n \u003cdiv id=\"podkey-toolbar\"\u003e\n \u003cdiv class=\"toolbar-left\"\u003e\n \u003cspan class=\"file-name\"\u003e${getFileName(window.location.href)}\u003c/span\u003e\n \u003cspan class=\"pod-indicator\"\u003e🔒 Solid Pod\u003c/span\u003e\n \u003c/div\u003e\n \u003cdiv class=\"toolbar-right\"\u003e\n \u003cbutton id=\"podkey-preview-toggle\" class=\"toolbar-btn\"\u003e\n 👁️ Preview\n \u003c/button\u003e\n \u003cbutton id=\"podkey-save\" class=\"toolbar-btn primary\"\u003e\n 💾 Save\n \u003c/button\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n\n \u003cdiv id=\"podkey-editor-wrapper\"\u003e\n \u003ctextarea id=\"podkey-markdown-editor\" spellcheck=\"false\"\u003e${escapeHtml(content)}\u003c/textarea\u003e\n \u003cdiv id=\"podkey-preview-pane\" style=\"display: none;\"\u003e\u003c/div\u003e\n \u003c/div\u003e\n\n \u003cdiv id=\"podkey-status-bar\"\u003e\n \u003cspan id=\"podkey-status\"\u003eReady\u003c/span\u003e\n \u003cspan id=\"podkey-word-count\"\u003e\u003c/span\u003e\n \u003c/div\u003e\n `;\n\n document.body.appendChild(editorContainer);\n\n // Initialize editor\n const editor = document.getElementById('podkey-markdown-editor');\n const preview = document.getElementById('podkey-preview-pane');\n const saveBtn = document.getElementById('podkey-save');\n const previewToggle = document.getElementById('podkey-preview-toggle');\n const status = document.getElementById('podkey-status');\n\n let previewMode = false;\n\n // Live preview toggle\n previewToggle.addEventListener('click', () =\u003e {\n previewMode = !previewMode;\n if (previewMode) {\n editor.style.display = 'none';\n preview.style.display = 'block';\n preview.innerHTML = renderMarkdown(editor.value);\n previewToggle.textContent = '✏️ Edit';\n } else {\n editor.style.display = 'block';\n preview.style.display = 'none';\n previewToggle.textContent = '👁️ Preview';\n }\n });\n\n // Auto-update preview\n let previewTimeout;\n editor.addEventListener('input', () =\u003e {\n clearTimeout(previewTimeout);\n previewTimeout = setTimeout(() =\u003e {\n if (previewMode) {\n preview.innerHTML = renderMarkdown(editor.value);\n }\n updateWordCount(editor.value);\n }, 300);\n });\n\n // Save functionality\n saveBtn.addEventListener('click', async () =\u003e {\n try {\n saveBtn.disabled = true;\n saveBtn.textContent = '💾 Saving...';\n status.textContent = 'Signing request...';\n\n // Create NIP-98 auth event\n const authEvent = {\n kind: 27235, // Solid auth event\n created_at: Math.floor(Date.now() / 1000),\n tags: [\n ['u', window.location.href],\n ['method', 'PUT']\n ],\n content: ''\n };\n\n // Sign with Nostr key\n const signedEvent = await window.nostr.signEvent(authEvent);\n\n status.textContent = 'Uploading...';\n\n // PUT to Solid pod\n const putResponse = await fetch(window.location.href, {\n method: 'PUT',\n headers: {\n 'Authorization': `Nostr ${btoa(JSON.stringify(signedEvent))}`,\n 'Content-Type': 'text/markdown'\n },\n body: editor.value\n });\n\n if (putResponse.ok) {\n status.textContent = '✅ Saved successfully';\n saveBtn.classList.add('success');\n setTimeout(() =\u003e {\n saveBtn.classList.remove('success');\n status.textContent = 'Ready';\n }, 2000);\n } else {\n throw new Error(`Save failed: ${putResponse.status} ${putResponse.statusText}`);\n }\n } catch (error) {\n console.error('[Podkey] Save error:', error);\n status.textContent = '❌ Save failed: ' + error.message;\n } finally {\n saveBtn.disabled = false;\n saveBtn.textContent = '💾 Save';\n }\n });\n\n // Keyboard shortcuts\n editor.addEventListener('keydown', (e) =\u003e {\n // Ctrl+S / Cmd+S to save\n if ((e.ctrlKey || e.metaKey) \u0026\u0026 e.key === 's') {\n e.preventDefault();\n saveBtn.click();\n }\n\n // Ctrl+P / Cmd+P to toggle preview\n if ((e.ctrlKey || e.metaKey) \u0026\u0026 e.key === 'p') {\n e.preventDefault();\n previewToggle.click();\n }\n });\n\n // Initial word count\n updateWordCount(content);\n}\n\nfunction renderMarkdown(text) {\n // Use marked.js or similar library\n // For now, basic rendering:\n return text\n .replace(/^### (.*$)/gim, '\u003ch3\u003e$1\u003c/h3\u003e')\n .replace(/^## (.*$)/gim, '\u003ch2\u003e$1\u003c/h2\u003e')\n .replace(/^# (.*$)/gim, '\u003ch1\u003e$1\u003c/h1\u003e')\n .replace(/\\*\\*(.*)\\*\\*/gim, '\u003cstrong\u003e$1\u003c/strong\u003e')\n .replace(/\\*(.*)\\*/gim, '\u003cem\u003e$1\u003c/em\u003e')\n .replace(/\\n/g, '\u003cbr\u003e');\n}\n\nfunction updateWordCount(text) {\n const words = text.trim().split(/\\s+/).length;\n const chars = text.length;\n document.getElementById('podkey-word-count').textContent =\n `${words} words · ${chars} characters`;\n}\n\nfunction getFileName(url) {\n return url.split('/').pop() || 'document.md';\n}\n\nfunction escapeHtml(text) {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n}\n\n// Initialize when page loads\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', injectMarkdownEditor);\n} else {\n injectMarkdownEditor();\n}\n```\n\n### 4. Styling\n\n```css\n/* src/styles/markdown-editor.css */\nbody.podkey-markdown-editor {\n margin: 0;\n padding: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n height: 100vh;\n overflow: hidden;\n}\n\n#podkey-editor-container {\n display: flex;\n flex-direction: column;\n height: 100vh;\n background: #ffffff;\n}\n\n#podkey-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n}\n\n.toolbar-left {\n display: flex;\n gap: 16px;\n align-items: center;\n}\n\n.file-name {\n font-weight: 600;\n font-size: 14px;\n}\n\n.pod-indicator {\n font-size: 12px;\n opacity: 0.9;\n}\n\n.toolbar-right {\n display: flex;\n gap: 8px;\n}\n\n.toolbar-btn {\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n background: rgba(255,255,255,0.2);\n color: white;\n cursor: pointer;\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.toolbar-btn:hover {\n background: rgba(255,255,255,0.3);\n}\n\n.toolbar-btn.primary {\n background: white;\n color: #667eea;\n font-weight: 600;\n}\n\n.toolbar-btn.primary:hover {\n background: #f0f0f0;\n}\n\n.toolbar-btn.success {\n background: #10b981 !important;\n color: white !important;\n}\n\n#podkey-editor-wrapper {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n#podkey-markdown-editor {\n flex: 1;\n padding: 24px;\n border: none;\n outline: none;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 14px;\n line-height: 1.6;\n resize: none;\n background: #fafafa;\n}\n\n#podkey-preview-pane {\n flex: 1;\n padding: 24px;\n overflow-y: auto;\n background: white;\n border-left: 1px solid #e5e7eb;\n}\n\n#podkey-preview-pane h1 { font-size: 2em; margin-top: 0; }\n#podkey-preview-pane h2 { font-size: 1.5em; }\n#podkey-preview-pane h3 { font-size: 1.2em; }\n\n#podkey-status-bar {\n display: flex;\n justify-content: space-between;\n padding: 8px 16px;\n background: #f9fafb;\n border-top: 1px solid #e5e7eb;\n font-size: 12px;\n color: #6b7280;\n}\n```\n\n### 5. Manifest Updates\n\n```json\n{\n \"content_scripts\": [\n {\n \"matches\": [\"\u003call_urls\u003e\"],\n \"js\": [\"src/injected.js\"],\n \"run_at\": \"document_start\",\n \"all_frames\": false\n },\n {\n \"matches\": [\"\u003call_urls\u003e\"],\n \"js\": [\"src/content-markdown.js\"],\n \"css\": [\"src/styles/markdown-editor.css\"],\n \"run_at\": \"document_idle\"\n }\n ],\n \"web_accessible_resources\": [\n {\n \"resources\": [\n \"src/nostr-provider.js\",\n \"src/styles/*.css\",\n \"lib/marked.min.js\"\n ],\n \"matches\": [\"\u003call_urls\u003e\"]\n }\n ],\n \"permissions\": [\n \"storage\",\n \"webRequest\",\n \"webNavigation\"\n ],\n \"host_permissions\": [\n \"\u003call_urls\u003e\"\n ]\n}\n```\n\n## User Experience Flow\n\n1. **User navigates to** `https://pod.example.com/public/notes.md`\n2. **Extension detects**:\n - ✅ Solid pod (via headers or well-known)\n - ✅ Markdown file (via URL/content-type)\n3. **Page transforms** into full-screen editor\n4. **User edits** with live preview\n5. **User clicks Save** (or Ctrl+S)\n6. **Extension signs** request with Nostr key (auto-approved if trusted origin)\n7. **Content saves** to pod via PUT request\n8. **Success notification** appears\n\n## Benefits\n\n- 🚀 **Zero friction**: Edit markdown files instantly, no downloads\n- 🔐 **Secure**: Authenticated via cryptographic signatures (Nostr)\n- 🎨 **Beautiful**: Modern, clean UI like HackMD\n- ⚡ **Fast**: Auto-auth for trusted pods, no prompts\n- 🌍 **Universal**: Works on ANY Solid pod, not just specific servers\n- 📝 **Familiar**: Standard keyboard shortcuts (Ctrl+S, Ctrl+P)\n- 👁️ **Live Preview**: See rendered markdown as you type\n\n## Settings UI\n\nAdd to popup settings:\n\n```javascript\n// Markdown Editor Settings\n{\n enabled: true,\n autoInject: true, // Auto-inject on .md files\n showPreview: false, // Start in preview mode\n theme: 'light', // light | dark\n fontSize: 14, // Editor font size\n autoSave: false, // Auto-save on change (with debounce)\n autoSaveDelay: 3000, // ms\n keyboardShortcuts: true\n}\n```\n\n## Challenges \u0026 Considerations\n\n### 1. **Conflict with Existing Editors**\n- Some Solid pods may already have editors\n- **Solution**: Add toggle in extension popup to disable/enable per-site\n\n### 2. **Content-Type Handling**\n- Some servers serve markdown as `text/plain` or `text/html`\n- **Solution**: Multi-strategy detection (URL + headers + content inspection)\n\n### 3. **Large Files**\n- Very large markdown files may be slow\n- **Solution**: Add size limit (e.g., 5MB), show warning for larger files\n\n### 4. **Permissions**\n- User may not have write access to the resource\n- **Solution**: Check WAC-Allow header, disable save button if no write access\n\n### 5. **Concurrent Edits**\n- Multiple users editing same file\n- **Solution**: Show warning if ETag changes, offer to reload or force save\n\n### 6. **Markdown Rendering**\n- Need a good markdown parser\n- **Solution**: Include marked.js or markdown-it as web-accessible resource\n\n## Implementation Phases\n\n### Phase 1: MVP (v0.0.3)\n- ✅ Detect Solid pods (header-based)\n- ✅ Detect markdown files\n- ✅ Inject basic editor (textarea + save button)\n- ✅ NIP-98 authenticated save\n\n### Phase 2: Enhanced Editor (v0.0.4)\n- ✅ Syntax highlighting\n- ✅ Live preview pane\n- ✅ Keyboard shortcuts\n- ✅ Word count\n- ✅ Modern UI/styling\n\n### Phase 3: Advanced Features (v0.0.5)\n- ✅ Auto-save\n- ✅ Version history (via Solid versioning)\n- ✅ Conflict detection\n- ✅ Dark mode\n- ✅ Settings panel\n- ✅ Per-site enable/disable\n\n## Acceptance Criteria\n\n- [ ] Extension detects Solid pods via HTTP headers\n- [ ] Extension detects markdown files (.md extension or content-type)\n- [ ] Editor injects cleanly without breaking page\n- [ ] Editor fetches and displays current markdown content\n- [ ] Save button creates NIP-98 signed request\n- [ ] Save succeeds with 200/204 response\n- [ ] Keyboard shortcuts work (Ctrl+S, Ctrl+P)\n- [ ] Preview pane renders markdown correctly\n- [ ] Works on JavaScriptSolidServer\n- [ ] Works on solidcommunity.net\n- [ ] Settings allow enabling/disabling per site\n- [ ] Error messages are user-friendly\n\n## Example Use Cases\n\n1. **Personal Wiki**: Edit your Solid pod wiki pages like Notion\n2. **Blog Posts**: Write blog posts in markdown, preview, and publish\n3. **Documentation**: Edit project docs hosted on Solid pods\n4. **Notes**: Quick note-taking across any Solid pod\n5. **Collaboration**: Share pod URL, collaborators edit with their own keys\n\n## Related Issues\n\n- #1 (Browser extension foundation)\n- Future: WYSIWYG editor mode\n- Future: Support for other formats (HTML, Turtle, JSON-LD)\n\n## Additional Resources\n\n- [NIP-98: HTTP Auth](https://github.com/nostr-protocol/nips/blob/master/98.md)\n- [Solid Protocol Spec](https://solidproject.org/TR/protocol)\n- [Marked.js](https://marked.js.org/) - Markdown parser\n- [HackMD](https://hackmd.io/) - Inspiration\n\n---\n\n**LLM Implementation Notes:**\n\nThis issue is designed to be fully implementable by an LLM. Key files to create/modify:\n\n1. `src/content-markdown.js` - Main editor injection logic\n2. `src/styles/markdown-editor.css` - Editor styling\n3. `src/background.js` - Add Solid pod detection via webRequest\n4. `manifest.json` - Add content script and permissions\n5. `lib/marked.min.js` - Include markdown parser\n\nThe code snippets above are production-ready and can be used directly. All edge cases and detection strategies are documented.\n","author":{"url":"https://github.com/melvincarvalho","@type":"Person","name":"melvincarvalho"},"datePublished":"2026-01-05T17:46:04.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/3/podkey/issues/3"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:ad17b7f2-d860-3d9a-87df-f1b4b93d1200 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | DF54:DF89D:4AF752:67615F:69774FD3 |
| html-safe-nonce | 597affc3e8e4c4e8b45561402283c01437f69ba80bdd3e3de1cbbd6011c79069 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJERjU0OkRGODlEOjRBRjc1Mjo2NzYxNUY6Njk3NzRGRDMiLCJ2aXNpdG9yX2lkIjoiNDQ0OTEyNjczOTMxMzM4MTMzMSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | f44727652c26eb68753ac7717298cdfd6d938e9182253e62510565b6f9da7c06 |
| hovercard-subject-tag | issue:3782350313 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/JavaScriptSolidServer/podkey/3/issue_layout |
| twitter:image | https://opengraph.githubassets.com/d6caddbb394d4aa9c67829f237fa29e40295ba1ffd5d8a241d7f0b4240901ae2/JavaScriptSolidServer/podkey/issues/3 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/d6caddbb394d4aa9c67829f237fa29e40295ba1ffd5d8a241d7f0b4240901ae2/JavaScriptSolidServer/podkey/issues/3 |
| og:image:alt | Markdown Editor Injection for Solid Pods (HackMD-style) Overview Add content script functionality to detect markdown files on Solid pods and inject a live editor interface (similar to HackMD), allo... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | melvincarvalho |
| hostname | github.com |
| expected-hostname | github.com |
| None | 3310064f35a62c06a4024ba37f41c06836f39376a095c2dfd2c4b693c34965be |
| turbo-cache-control | no-preview |
| go-import | github.com/JavaScriptSolidServer/podkey git https://github.com/JavaScriptSolidServer/podkey.git |
| octolytics-dimension-user_id | 205442424 |
| octolytics-dimension-user_login | JavaScriptSolidServer |
| octolytics-dimension-repository_id | 1128353485 |
| octolytics-dimension-repository_nwo | JavaScriptSolidServer/podkey |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 1128353485 |
| octolytics-dimension-repository_network_root_nwo | JavaScriptSolidServer/podkey |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 67d5f8d1d53c3cc4f49fc3bb8029933c3dc219e6 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width