René's URL Explorer Experiment


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

direct link

Domain: github.com


Hey, it has json ld scripts:
{"@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-controllervoltron_issues_fragments
route-actionissue_layout
fetch-noncev2:ad17b7f2-d860-3d9a-87df-f1b4b93d1200
current-catalog-service-hash81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114
request-idDF54:DF89D:4AF752:67615F:69774FD3
html-safe-nonce597affc3e8e4c4e8b45561402283c01437f69ba80bdd3e3de1cbbd6011c79069
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJERjU0OkRGODlEOjRBRjc1Mjo2NzYxNUY6Njk3NzRGRDMiLCJ2aXNpdG9yX2lkIjoiNDQ0OTEyNjczOTMxMzM4MTMzMSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9
visitor-hmacf44727652c26eb68753ac7717298cdfd6d938e9182253e62510565b6f9da7c06
hovercard-subject-tagissue:3782350313
github-keyboard-shortcutsrepository,issues,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/issues_fragments/issue_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/JavaScriptSolidServer/podkey/3/issue_layout
twitter:imagehttps://opengraph.githubassets.com/d6caddbb394d4aa9c67829f237fa29e40295ba1ffd5d8a241d7f0b4240901ae2/JavaScriptSolidServer/podkey/issues/3
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/d6caddbb394d4aa9c67829f237fa29e40295ba1ffd5d8a241d7f0b4240901ae2/JavaScriptSolidServer/podkey/issues/3
og:image:altMarkdown 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:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
og:author:usernamemelvincarvalho
hostnamegithub.com
expected-hostnamegithub.com
None3310064f35a62c06a4024ba37f41c06836f39376a095c2dfd2c4b693c34965be
turbo-cache-controlno-preview
go-importgithub.com/JavaScriptSolidServer/podkey git https://github.com/JavaScriptSolidServer/podkey.git
octolytics-dimension-user_id205442424
octolytics-dimension-user_loginJavaScriptSolidServer
octolytics-dimension-repository_id1128353485
octolytics-dimension-repository_nwoJavaScriptSolidServer/podkey
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id1128353485
octolytics-dimension-repository_network_root_nwoJavaScriptSolidServer/podkey
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release67d5f8d1d53c3cc4f49fc3bb8029933c3dc219e6
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/JavaScriptSolidServer/podkey/issues/3#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FJavaScriptSolidServer%2Fpodkey%2Fissues%2F3
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub SparkBuild and deploy intelligent appshttps://github.com/features/spark
GitHub ModelsManage and compare promptshttps://github.com/features/models
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
GitHub SponsorsFund open source developershttps://github.com/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/accelerator
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FJavaScriptSolidServer%2Fpodkey%2Fissues%2F3
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fissues_fragments%2Fissue_layout&source=header-repo&source_repo=JavaScriptSolidServer%2Fpodkey
Reloadhttps://github.com/JavaScriptSolidServer/podkey/issues/3
Reloadhttps://github.com/JavaScriptSolidServer/podkey/issues/3
Reloadhttps://github.com/JavaScriptSolidServer/podkey/issues/3
JavaScriptSolidServer https://github.com/JavaScriptSolidServer
podkeyhttps://github.com/JavaScriptSolidServer/podkey
Notifications https://github.com/login?return_to=%2FJavaScriptSolidServer%2Fpodkey
Fork 0 https://github.com/login?return_to=%2FJavaScriptSolidServer%2Fpodkey
Star 1 https://github.com/login?return_to=%2FJavaScriptSolidServer%2Fpodkey
Code https://github.com/JavaScriptSolidServer/podkey
Issues 1 https://github.com/JavaScriptSolidServer/podkey/issues
Pull requests 0 https://github.com/JavaScriptSolidServer/podkey/pulls
Actions https://github.com/JavaScriptSolidServer/podkey/actions
Projects 0 https://github.com/JavaScriptSolidServer/podkey/projects
Security 0 https://github.com/JavaScriptSolidServer/podkey/security
Insights https://github.com/JavaScriptSolidServer/podkey/pulse
Code https://github.com/JavaScriptSolidServer/podkey
Issues https://github.com/JavaScriptSolidServer/podkey/issues
Pull requests https://github.com/JavaScriptSolidServer/podkey/pulls
Actions https://github.com/JavaScriptSolidServer/podkey/actions
Projects https://github.com/JavaScriptSolidServer/podkey/projects
Security https://github.com/JavaScriptSolidServer/podkey/security
Insights https://github.com/JavaScriptSolidServer/podkey/pulse
New issuehttps://github.com/login?return_to=https://github.com/JavaScriptSolidServer/podkey/issues/3
New issuehttps://github.com/login?return_to=https://github.com/JavaScriptSolidServer/podkey/issues/3
Markdown Editor Injection for Solid Pods (HackMD-style)https://github.com/JavaScriptSolidServer/podkey/issues/3#top
https://github.com/melvincarvalho
https://github.com/melvincarvalho
melvincarvalhohttps://github.com/melvincarvalho
on Jan 5, 2026https://github.com/JavaScriptSolidServer/podkey/issues/3#issue-3782350313
Implement Automatic NIP-98 HTTP Authentication #1https://github.com/JavaScriptSolidServer/podkey/issues/1
NIP-98: HTTP Authhttps://github.com/nostr-protocol/nips/blob/master/98.md
Solid Protocol Spechttps://solidproject.org/TR/protocol
Marked.jshttps://marked.js.org/
HackMDhttps://hackmd.io/
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.