Files
myworkspace/Linkding Browser Extension/LinkdingSync/docs/design.md

7.9 KiB

LinkdingSync Extension - Design Document

Overview

linkdingsync is a Firefox browser extension that synchronizes bookmarks with a self-hosted Linkding instance. It supports folder hierarchy, bi-directional sync, configurable sync modes, and tag-based bundle management.

Project Location

Linkding Browser Extension/LinkdingSync/

Extension Name

linkdingsync - Firefox extension name (manifest.json)


1. Data Storage Structure

Configuration (stored in browser.storage.local)

{
  "serverUrl": "https://links.blabber1565.com",
  "apiKey": "your-api-token-here",
  "bundleTag": "bundle_personal_firefox_1",
  "syncMode": "bi-directional",
  "autoGenerateTags": false,
  "lastSyncTimestamp": 1715012345678
}

Storage Areas

  • browser.storage.local - Persistent data per browser profile
  • browser.storage.session - Temporary session data

Supported Values

Value Description
bi-directional Replicate both directions; keep both versions
write-only Browser is authoritative source; update Linkding only
read-only Linkding is authoritative source; download only

Default: bi-directional


2. Bookmark Notes Structure

The notes field uses a JSON-compatible structure with versioning for forward compatibility:

{
  "version": 1.0,
  "path": "Work/Resources/Development",
  "userNotes": "Development resources and references",
  "autoTags": [
    {"name": "Work"},
    {"name": "Resources"},
    {"name": "Development"}
  ],
  "bundleTag": "bundle_personal_firefox_1"
}

Display Format

  • Only show userNotes in the UI
  • path and autoTags are hidden from regular users

Version Handling

  • version 1.0: Basic structured format with path, userNotes, autoTags
  • version 2.0: Adds bundleTag field for tag-based bundle identification
  • Extension version tracking: Uses extension version number for notes version
  • Backward compatibility:
    • Old bookmarks without structured notes are detected
    • Non-JSON notes are migrated to structured format
    • Old notes get version: 1.0 and existing text in userNotes
    • Future fields are ignored by older versions

Auto-generate Tags Setting

  • Default: false (disabled)
  • When true, extracts folder names from path as tag suggestions
  • User must organize folders intentionally for tag auto-generation to work correctly

3. Bundle/Tag Configuration

Instead of creating actual Linkding bundles, we use Linkding's "required tags" feature:

Bundle Tag Convention

All bookmarks in a bundle must have the bundle tag. The bundle tag name follows this pattern:

bundle_{BUNDLE_NAME}_{BROWSER}

Examples:

  • bundle_personal_firefox_1
  • bundle_work_chrome_1
  • bundle_personal_edge_1

Linkding Query Parameters

In Linkding, create a bundle with these parameters:

  • Search: (empty)
  • Required tags: {bundleTag}
  • Any tags: (empty)
  • All tags: (empty)
  • Excluded tags: (empty)

This means all bookmarks with the bundle tag appear in this bundle.

Updating Extension Version

The extension version is used as the notes version:

  • Extension v1.0.x → notes version 1.0
  • Extension v2.0.x → notes version 2.0
  • Extension v1.0.1 → notes version 1.0 (patch versions don't change notes version)

4. Extension File Structure

LinkdingSync/
├── manifest.json              # Firefox manifest v2
├── popup.html                 # Main extension popup
├── popup.css                  # Popup styling
├── popup.js                   # Popup UI logic
├── background.html            # Settings/config page
├── background.js              # Service worker
├── README.md                  # User documentation
├── docs/
│   ├── design.md              # Design document
│   └── TODOs.txt             # Version compatibility notes
└── icons/
    ├── icon-48.svg            # 48x48 icon
    └── icon-96.svg            # 96x96 icon

5. Key Features

Popup UI

  • Quick bookmark add with optional notes
  • Sync status indicator
  • Settings button → opens config page

Config Page (background.html)

  • Server URL input (with validation)
  • API key input (with "Get from Linkding Settings" guidance)
  • Bundle tag input (e.g., "bundle_personal_firefox_1")
  • Sync mode selector (bi-directional | write-only | read-only)
  • Auto-generate tags toggle
  • Last sync timestamp (human-readable with timezone)
  • Test connection button
  • Save Settings button
  • Reset config button

Background Service

  • Monitor bookmark events (add, remove, modify)
  • Perform sync operations with Linkding API
  • Cache recent API responses
  • Handle errors and show notifications
  • Apply bundle tag to all new bookmarks
  • Migrate old notes to structured format

6. Sync Logic Flow

1. Browser bookmark change detected
   ↓
2. Check syncMode:
   - read-only: download from Linkding only
   - write-only: sync to Linkding only
   - bi-directional: sync both directions
   ↓
3. For new bookmarks:
   - Add bundleTag to notes
   - Check if URL already in Linkding
   - If no → create new bookmark with bundle tag
   - If yes + different URL → create new bookmark
   - If yes + same URL → update notes (keep title/description)
   ↓
4. For updates (same URL, different folder):
   - Update path in notes
   - Merge with existing notes
   - Apply sync mode rules
   ↓
5. For deletions:
   - write-only → delete from Linkding
   - read-only → ignore (keep Linkding version)
   - bi-directional → delete from Linkding
   ↓
6. Migrate old notes:
   - If notes not JSON or lacks version field → treat as old notes
   - Convert to structured format with version 1.0
   - Preserve existing content in userNotes

7. Notes Migration

Old Notes Detection

Old notes are detected if:

  • notes is not valid JSON, OR
  • notes doesn't contain a version field

Migration Process

  1. Parse existing notes
  2. If invalid/non-JSON → create structured notes with:
    {
      "version": 1.0,
      "path": "",
      "userNotes": "<existing text here>",
      "autoTags": [],
      "bundleTag": "<from config>"
    }
    
  3. If valid but old version → update version field
  4. If same or newer version → keep as-is

Forward Compatibility

When new fields are added to notes structure:

  • Older extension versions ignore unknown fields
  • Newer extension versions add new fields
  • This allows gradual feature rollouts

8. API Endpoints Used

Authentication

Authorization: Token <Token>

Bookmarks

  • GET /api/bookmarks/ - List bookmarks
  • GET /api/bookmarks/check/?url=... - Check if URL is already bookmarked
  • POST /api/bookmarks/ - Create bookmark
  • PUT/PATCH /api/bookmarks/<id>/ - Update bookmark
  • DELETE /api/bookmarks/<id>/ - Delete bookmark

9. Implementation Status

Phase 1: Core Setup

  • Create manifest.json with options_ui
  • Create popup HTML/CSS/JS
  • Create background service worker
  • Implement storage helpers

Phase 2: Sync Logic

  • Implement bookmark manipulation
  • Implement notes parser with versioning
  • Implement sync logic
  • Implement conflict resolution

Phase 3: Configuration UI

  • Create config page
  • Implement config form logic
  • Add API key guidance

Phase 4: Polish

  • Add icons
  • Add error handling
  • Add notifications
  • Implement notes migration
  • Implement tag-based bundle approach

10. Version History

Version Date Changes
0.1.0 2026-05-06 Initial design document
1.0.0 2026-05-06 Initial implementation
1.0.1 TBD Tag-based bundle support
1.0.2 TBD Notes version migration

11. Notes

This document should be referenced during implementation to ensure all requirements are met. Any deviations from this design should be documented here.


Last Updated: 2026-05-06