Fancy Links is a browser extension that transforms plain URLs into friendly links with included page titles. Perfect for sharing in chat apps, Reddit, GitHub, documentation, and anywhere formatted links look better than bare URLs.
Browser Support:
- Firefox (minimum version 109)
Interested in other browsers? Please vote for Chrome support or suggest a new browser!
Install the latest stable version from the Firefox Add-ons store.
Want to test new features before they're released? You can install pre-release versions:
- Visit our Releases page
- Look for versions marked as "Pre-release" (e.g., v1.5.0-rc1)
- Download the
.xpi
file from the pre-release - Open Firefox and drag the downloaded file into the browser window
- Click "Add" when prompted to install
Note: Pre-release versions:
- Are signed by Mozilla and safe to install
- Will automatically update to the stable version when it's released
- May contain experimental features or bugs
- Your feedback is valuable! Please report any issues
- Markdown (Reddit, Discord, Obsidian, Notion, etc.):
[Title](URL)
- HTML:
<a href="URL">Title</a>
- Plain Text:
Title - URL
- URL with Title Parameter:
URL?_title=Page_Title
- Toolbar Button: Click to open popup with all format options
- Keyboard Shortcut:
Alt+Shift+C
(Windows/Linux) /Opt+Shift+C
(macOS) for quick copy with default format (can be changed in Settings) - Live Previews: See exactly how each format will look before copying
- Settings Page: Configure default format, notifications, and clean URL feature
- Clean URLs: Optional removal of tracking parameters (UTM, Facebook, etc.)
- Cross-Platform: Works on Windows, macOS, and Linux
- Click the Fancy Links icon in the toolbar
- Choose from the different link formats
- Click any format button to copy instantly
- Navigate to any webpage
- Press the keyboard shortcut (default:
Alt+Shift+C
on Windows/Linux,Opt+Shift+C
on macOS) - The formatted link is copied using your default format
You can change your default format by clicking the Fancy Links toolbar icon and then selecting "Set Default" on your preferred link format.
Click the Fancy Links toolbar icon and select the Gear icon to see all available settings, including:
- Notifications
- Toolbar button badges
- View keyboard shortcuts
- Enable/disable the clean URL feature to remove tracking parameters
- Enable Debug mode
- Customize bug reporting
To customize the keyboard shortcut:
- Go to
about:addons
in Firefox - Click Extensions in the sidebar
- Click the gear icon (⚙️) → "Manage Extension Shortcuts"
- Find "Fancy Links" and customize the shortcut
- The popup will automatically show your custom shortcut
# Clone the repository
git clone https://github.com/evanwon/fancy-links.git
cd fancy-links
npm ci --ignore-scripts
# We're using `npm ci` instead of `npm install` for security reasons, and prevent execution of install scripts for security
# Note: If you don't have a package-lock.json, run: npm install --ignore-scripts
# Install web-ext globally (if not already installed)
npm install -g web-ext --ignore-scripts
# Run in development mode (hot reloads on changes)
web-ext run --source-dir=src
# Or use npm script:
npm run dev
# Run tests
npm test # Run all tests
npm run test:watch # Watch mode
npm run test:coverage # Coverage report
# Lint and build
npm run lint:firefox # Check for issues
npm run build # Build .zip file
npm run build:firefox # Lint and build
npm run test:build # Test, lint, and build
If you want to run local builds of the extension in your regular browser (not the sandbox test browser), you can install it for your current browsing session by following these instructions:
- Build the
.xpi
as shown above, or download the latest.xpi
file from Releases. - Open Firefox and navigate to about:debugging#/runtime/this-firefox
- Click "Load Temporary Add-on"
- Select the downloaded
.xpi
file
Note that using this about:debugging
approach will only load the plugin for your current session.
This project includes VSCode debugging configuration for the Debugger for Firefox extension.
- Install the "Debugger for Firefox" extension in VSCode if not already installed
- Open the project in VSCode
- Press
F5
or go to Run and Debug panel (Ctrl+Shift+D
) - The default "Debug Fancy Links (Auto-Reload)" configuration will:
- Start Firefox with the extension loaded
- Automatically reload the extension when you save changes
- Allow you to set breakpoints in any JavaScript file
- Debug Fancy Links (Auto-Reload) (default): Best for development - auto-reloads on file changes
- Debug Fancy Links: Basic debugging without auto-reload
- Breakpoints work in all extension scripts (background, popup, content scripts)
- Use the Debug Console to execute commands in the extension context
- Run
web-ext run --source-dir=src
to start development Firefox - Open
test/manual.html
for comprehensive testing scenarios - Test all format buttons and keyboard shortcut
-
Configure GitHub Secrets (Settings → Secrets and variables → Actions → Secrets):
AMO_API_KEY
: Your AMO API issuer IDAMO_API_SECRET
: Your AMO API secret
-
Configure GitHub Variables (Settings → Secrets and variables → Actions → Variables):
AMO_SUBMISSION_ENABLED
: Set totrue
to enable automatic AMO submission on tags
The build system automatically detects pre-releases based on version suffixes:
rc[0-9]+
- Release candidates (e.g.,1.5.0-rc1
,1.5.0-rc2
)beta[0-9]+
- Beta versions (e.g.,1.5.0-beta1
)alpha[0-9]+
- Alpha versions (e.g.,1.5.0-alpha1
)
# 1. Update src/manifest.json with BOTH version fields:
# - "version": Use PREVIOUS stable + .9.N (e.g., "1.4.9.1" for 1.5.0-rc1)
# - "version_name": Target version with suffix (e.g., "1.5.0-rc1")
# 2. Commit changes
git add -A && git commit -m "Prepare v1.5.0-rc1 pre-release"
# 3. Create and push tag (triggers GitHub Actions)
git tag v1.5.0-rc1
git push origin v1.5.0-rc1
Important: The version
field must use the PREVIOUS stable version as base to ensure proper update paths. See VERSIONING.md for detailed examples.
Pre-release behavior:
- ✅ Automatically signed by Mozilla (via unlisted channel)
- ✅ Creates GitHub pre-release with download link
- ❌ NOT submitted to AMO public listing
- 📦 Distributed via GitHub releases page only
- 🔄 Auto-updates to stable version when released
Releases are automatically built and optionally submitted to AMO when you push a version tag:
# 1. Update version in src/manifest.json (no suffix, e.g., 1.5.0)
# 2. Commit changes
git add -A && git commit -m "Version 1.5.0"
# 3. Create and push tag (triggers GitHub Actions)
git tag v1.5.0
git push origin v1.5.0
The workflow will:
- Run tests and linting
- Build the extension
- Create a GitHub release
- Submit to AMO (if
AMO_SUBMISSION_ENABLED
variable istrue
)
For testing builds without creating a release:
- Go to Actions tab
- Select "Build and Release" workflow
- Click "Run workflow"
- Configure options:
create_release
: Create GitHub release (default: false)submit_to_amo
: Submit to AMO (default: false)channel
: AMO channel -listed
(public) orunlisted
(self-distribution)
- Click "Run workflow"
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature-name
- Make your changes
- Test thoroughly with
web-ext run --source-dir=src
- Commit:
git commit -m 'Crisp, specific definition of your change'
- Push:
git push origin feature/your-feature-name
- Open a Pull Request
fancy-links/
├── src/ # Extension source code (production files only)
│ ├── manifest.json # Extension manifest
│ ├── background/ # Background scripts
│ ├── popup/ # Toolbar popup UI
│ ├── options/ # Settings page
│ ├── formats/ # Format registry and logic
│ ├── utils/ # Shared utilities (clean-url, clipboard, etc.)
│ └── icons/ # Extension icons (PNG)
├── test/ # Automated and manual tests
├── tools/ # Development utilities (icon generation)
├── design/ # Design files and assets
├── .github/ # GitHub Actions workflows
└── dist/ # Build output (generated)
- Uses Manifest V2 (Firefox still prefers MV2 over MV3)
- No external dependencies - pure HTML/CSS/JS
- Modular architecture for easy format addition
- Browser-compatible format system (avoids Node.js require() issues)
- Clean separation between extension code (
src/
) and development files - Comprehensive sanitization prevents XSS and format-breaking
clipboardWrite
: Copy formatted text to clipboardactiveTab
: Access current tab's title and URLstorage
: Save user preferencesnotifications
: Show copy confirmation messages
This project is licensed under the MIT License - see LICENSE for details.
Developed using Claude Code, but don't worry, I included please bro, no mistakes
multiple times in the prompt.
(In seriousness, I wanted to use this as an opportunity to try out Claude Code-first development. At least at the start of this project, I'm trying to primarily use Claude Code, and I included CLAUDE.md
in the repo so you can see how I'm trying to guide the tool. For any Claude-driven commits, Claude will note itself as a co-author in the commit message. I'm still intervening quite a bit and haven't yet been bold enough to set it in full-auto mode, but maybe we'll get there eventually.)