Shipped tool
Discord Server Tracker
A Manifest V3 browser extension that turns Discord server-listing activity into a searchable local history with favourites, notes, statistics and archive management.
- Role
- Product & Extension Engineering
- Period
- 2023—present
- Categories
- Frontend
- Stack
- Manifest V3JavaScriptViteChrome APIsContent ScriptsService WorkerHTMLCSS
Key metrics
- Weekly users
- 70
- Owner-approved weekly usage aggregate for the published extension.
- Current approved snapshot; this is not a public Chrome Web Store counter.
- Supported server directories
- 4
- Distinct listing sites covered by release v4.0.2.
- Current release scope, counted by supported host.
- Requested extension permission
- 1
- The Manifest V3 permissions list contains only storage.
- Host matches are documented separately and are not presented as extension permissions.
Overview
Server listing sites are useful for discovery, but the browsing trail disappears quickly. Remembering which communities looked relevant, when they were visited and why they were worth returning to becomes a manual task spread across tabs or external notes.
Discord Server Tracker captures an explicit join-button interaction on supported listing websites and turns it into a browser-local activity library. The compact popup answers quick questions; the full dashboard adds search, filters, visit history, favourites, attached notes, statistics and a reversible archive.
Challenge
The four supported listing websites expose different markup, identifiers and join-link behaviour, and some update their server cards dynamically. Capture has to recognize the same user intent without turning the content script into one site-specific monolith.
Manifest V3 background workers are short-lived. The popup, dashboard and content scripts still need one predictable path to local state even when the worker is restarted between interactions.
Existing users already have local history in older record shapes. New fields for first visit, favourites, archive state, notes and tags must not discard that history, while imported backups need understandable merge and replace semantics.
Solution
A content script delegates site-specific DOM reading to small adapters. When a supported join control is activated, it normalizes the server identity, source, links and visit timestamp, updates the local record and reflects tracked state back on the listing page.
The MV3 service worker provides a narrow message bridge around chrome.storage.local. Popup and dashboard code normalize records when reading them, write migrated shapes back in place and keep history, preferences and user annotations on the device without an account or remote service.
The popup focuses on recent, favourite and most-visited servers with direct search and actions. The dashboard expands the same data into aggregate activity, source and date filters, sorting, complete visit history, notes, favourites and archive management. Settings cover language, system/light/dark themes, time format, export, import and reset.
Responsibilities
- Define the product around remembered discovery and return visits rather than passive global browsing history.
- Implement adapters for server-discord.com, myserver.gg, discordserver.info and disboard.org.
- Build content-script capture and listing-page feedback for supported join-button interactions.
- Design the MV3 service-worker message boundary and browser-local record model.
- Develop the compact popup and full dashboard with search, filters, statistics, notes, favourites, history and archive actions.
- Implement JSON export and import with explicit merge or replace modes and in-place migration of legacy records.
- Refactor legacy monolithic scripts into modular Vite entry points and package the Chrome MV3 release archive.
Architecture
Interface
Popup quick views
Searchable dashboard
Services
Content script event capture
MV3 service worker
Merge or replace import
Legacy record migration
Data
Local history storage
Automation
Supported listing websites
Infrastructure
Vite-built MV3 package
Supported join-button interaction
Supported listing websites -> Content script event capture
Normalized server and visit event
Content script event capture -> MV3 service worker
Local read, write or removal
MV3 service worker -> Local history storage
Recent and favourite quick views
Local history storage -> Popup quick views
Search, statistics and archive state
Local history storage -> Searchable dashboard
Validated merge or replace
Merge or replace import -> Local history storage
Normalized legacy record
Legacy record migration -> Local history storage
Built content entry point
Content script event capture -> Vite-built MV3 package
Manifest V3 background lifecycle
MV3 service worker -> Vite-built MV3 package
Packaged browser action
Popup quick views -> Vite-built MV3 package
Packaged full-page interface
Searchable dashboard -> Vite-built MV3 package
Technical decisions
Track explicit join intent
- Problem
- Recording every page view would create noisy history and broaden the extension beyond the action the user actually wants to remember.
- Decision
- Capture only supported join-button interactions and store the associated server record and timestamp.
- Reason
- Each visit count represents deliberate interest rather than passive navigation.
- Trade-off
- A server viewed without activating its join control is intentionally absent from the library.
Isolate listing websites behind adapters
- Problem
- Each supported source uses different selectors, identifiers and URL patterns, and direct conditionals inside the event handler would become fragile.
- Decision
- Keep source-specific extraction and link construction in site adapters while sharing one capture lifecycle.
- Reason
- A markup change stays bounded to one adapter and the stored record remains consistent across sources.
- Trade-off
- Supported sites still require maintenance when their public markup changes.
Keep the complete library local
- Problem
- A hosted account would add authentication, synchronization and privacy obligations to a local activity-history tool.
- Decision
- Use chrome.storage.local through a narrow MV3 message bridge and request only the storage permission.
- Reason
- History, notes and preferences remain on the user's device and the extension works without a backend.
- Trade-off
- Cross-device continuity depends on explicit JSON export and import rather than automatic sync.
Normalize and migrate records on read
- Problem
- Legacy records use older field names and may not contain the newer history, favourite, archive or note fields.
- Decision
- Normalize every recognized record into the current shape, derive safe defaults and persist only entries that changed.
- Reason
- Existing history moves forward without a destructive one-time reset.
- Trade-off
- The read path owns compatibility logic and must remain careful with malformed imported data.
Separate quick access from library management
- Problem
- A browser popup is efficient for a few recent records but too constrained for statistics, dense filters and archive work.
- Decision
- Keep recent, favourite and most-visited views in the popup and move full management into a dedicated dashboard.
- Reason
- Each interface matches the time and space available to the task.
- Trade-off
- The extension maintains two coordinated presentations of the same local data.
Media
Gallery
Outcomes
- Discord Server Tracker is available as a standalone Chrome Web Store extension with a public source repository and a complete product workflow.
- Supported join interactions become a searchable and user-curated local history instead of disappearing after the listing tab closes.
- Migration, merge/replace import and modular packaging let the extension evolve without presenting demo statistics as real adoption or activity claims.
Verified highlights
- Release v4.0.2 is the current verified Chrome Web Store and source release.
- The background service worker exposes bounded local-storage message handlers for extension contexts.
- The popup provides recent, favourite and most-visited views, search and direct server actions.
- The dashboard provides source/date filters, sorting, activity statistics, full visit history, notes, favourites and archive management.
- Stored records are normalized in place from legacy fields, while JSON import supports merge and replace modes.
- English and Russian interfaces support system, light and dark themes plus 12-hour and 24-hour time formats.
- The active Vite build separates popup, dashboard, background and content entry points and can package a root-level MV3 archive.
Learnings
- Small browser tools become more useful when capture is tied to a meaningful user action and retrieval receives as much design attention as collection.
- Local-first does not remove data-lifecycle work: schema migration, import conflict rules, reset scope and browser-worker restarts still need explicit behaviour.