A simple bookmarking service in memory of del.icio.us, built with vanilla PHP and JavaScript.
- Dashboard: View all your bookmarks with search and filtering
- Tag System: Organize bookmarks with tags, with tag cloud sidebar
- Bookmarklet: Quick bookmark addition from any webpage
- Private/Public: Mark bookmarks as private or public
- Simple Auth: Password-based authentication for single-user setup
- SQLite Database: No database server required
- Import: Import bookmarks from Netscape HTML or Pinboard JSON files
- WordPress Integration: Auto-post tagged bookmarks to WordPress (optional)
- Manual Publishing: One-click publish buttons for individual bookmarks
- PHP 7.4 or higher
- SQLite extension (usually enabled by default)
- Web server (Apache/Nginx) or PHP built-in server
-
Clone or download this repository
-
Set up your password hash:
Option A: Web-based setup (Easiest - Recommended)
Start your web server, then visit:
http://localhost:8000/setup-password-web.phpEnter your password and copy the generated hash. Important: Delete this file after use for security!
Option B: Command line (if PHP is installed)
Generate a password hash using PHP:
php -r "echo password_hash('your_password_here', PASSWORD_DEFAULT);"On macOS, PHP might be in a different location. Try:
/usr/bin/php -r "echo password_hash('your_password_here', PASSWORD_DEFAULT);" # or if installed via Homebrew: /opt/homebrew/bin/php -r "echo password_hash('your_password_here', PASSWORD_DEFAULT);"
After generating the hash:
Update
includes/config.phpand set thePASSWORD_HASHconstant, or set it as an environment variable:export SHB_PASSWORD_HASH='your_hash_here'
-
Create the data directory:
mkdir -p data chmod 755 data
-
The database will be created automatically on first run.
-
Start your web server:
php -S localhost:8000
Or use Apache/Nginx with proper configuration.
-
Navigate to
http://localhost:8000(or your configured domain) -
Log in with your password
- View Bookmarks: All bookmarks are displayed on the main page
- Search: Use the search box to find bookmarks by title, URL, or description
- Filter by Tag: Click any tag in the sidebar to filter bookmarks
- Filter by Private: When logged in, a "Private" tag appears at the top of the sidebar to view only private bookmarks
- URL Parameters: Filter state is reflected in the URL (
?tag=jquery,?private=1,?search=...) - shareable and bookmarkable - Pagination: Navigate through pages of bookmarks (configurable in Settings)
- Publish to WordPress: If WordPress is configured, each bookmark has a π€ button to manually publish to WordPress
- Visit the Settings page and drag the bookmarklet to your browser toolbar.
- Visit any webpage
- Optionally select text on the page
- Click your bookmarklet bookmark
- A popup will open with pre-filled URL and title
- Add description, tags, and mark as private if needed
- Click "Save Bookmark"
- Go to Settings β Import Bookmarks
- Upload a Netscape-style HTML file (exported from Chrome, Firefox, Safari, etc.) or a Pinboard JSON file
- Optionally add additional tags to all imported bookmarks
- Review and confirm the import. Undo is available.
You can also add bookmarks programmatically using the API endpoints.
Most API endpoints require authentication via session (except public read endpoints).
GET /api/bookmarks.php- List bookmarks (supports?tag=,?search=,?page=,?private=) - PublicPOST /api/bookmarks.php- Create bookmark - Requires AuthPUT /api/bookmarks.php- Update bookmark - Requires AuthDELETE /api/bookmarks.php?id=X- Delete bookmark - Requires Auth
GET /api/tags.php- Get all tags (supports?q=for autocomplete) - PublicDELETE /api/tags.php- Delete tag - Requires Auth
GET /api/bookmarklet.php?url=...- Get existing bookmark by URL - Requires AuthPOST /api/bookmarklet.php- Create bookmark via bookmarklet (CORS enabled) - Requires Auth
GET /api/settings.php- Get all settings - PublicPUT /api/settings.php- Update settings - Requires Auth
GET /api/import.php- Get import history - Requires AuthPOST /api/import.php- Import bookmarks from file - Requires AuthDELETE /api/import.php- Undo an import - Requires Auth
POST /api/wp-test-connection.php- Test WordPress connection - Requires AuthGET /api/wp-publish.php?bookmark_id=X- Check if bookmark exists in WordPress - Requires AuthPOST /api/wp-publish.php- Publish bookmark to WordPress - Requires Auth
GET /api/auth.php?action=status- Check authentication status - PublicPOST /api/auth.php- Login or logout - Public for login, Auth for logout
selfhostedbookmarks/
βββ api/ # API endpoints
β βββ auth.php
β βββ bookmarks.php
β βββ bookmarklet.php
β βββ tags.php
β βββ settings.php
β βββ import.php
β βββ wp-test-connection.php
β βββ wp-publish.php
βββ assets/
β βββ css/
β β βββ style.css
β βββ js/
β βββ api.js
β βββ bookmarklet.js
β βββ dashboard.js
βββ includes/
β βββ auth.php
β βββ config.php
β βββ config.php.example
β βββ functions.php
βββ scripts/
β βββ shb_thc_to_wp.php # WordPress sync script
βββ sql/
β βββ schema.sql
β βββ migrations/
β βββ 001_add_imports_table.sql
βββ data/ # SQLite database (gitignored)
βββ bookmarklet-popup.php # Bookmarklet popup page
βββ index.php # Dashboard
βββ login.php # Login page
βββ settings.php # Settings page
βββ tags.php # Tags page
βββ import.php # Import page
βββ bookmarklet.js # Bookmarklet code
βββ README.md
βββ TECHNICAL_DOCUMENTATION.md
βββ CLOUDFLARE.md
- Change the default password hash in production
- Use HTTPS in production (required for clipboard access in bookmarklet)
- Consider adding rate limiting for API endpoints
- The bookmarklet requires you to be logged in (uses session cookies)
Access the Settings page (requires login) to configure:
- Tags Alphabetical: Sort tags alphabetically vs. order added
- Show URL: Display URL under bookmark title
- Show Date/Time: Show full timestamp vs. date only
- Bookmarks per Page: Pagination size (1-1000 or unlimited)
- Tag Threshold: Minimum tag count to show in sidebar
- Import from Netscape HTML files (Chrome, Firefox, Safari exports)
- Import from Pinboard JSON files
- Add additional tags to all imported bookmarks
- Undo imports if needed
- Configure WordPress connection
- Set watch tag for auto-posting
- Configure WordPress tags and categories
- Test connection before use
- Edit
includes/config.phpfor site name and configuration - Modify
assets/css/style.cssfor styling - Update database schema in
sql/schema.sqlif needed
Database errors: Ensure the data/ directory is writable by the web server.
Bookmarklet not working:
- Make sure you've updated the domain in
bookmarklet.js - Ensure you're logged in (bookmarklet uses session cookies)
- For clipboard access, the site must be served over HTTPS
Session issues: Check PHP session configuration and ensure sessions directory is writable.
SelfHostedBookmarks can automatically post bookmarks to your WordPress site. This feature supports both automated (scheduled) and manual publishing.
- Go to Settings β WordPress Auto-Post
- Fill in your WordPress connection details:
- SHB Base URL: Your SelfHostedBookmarks installation URL
- WordPress Base URL: Your WordPress site root URL (where
/wp-json/lives) - WordPress Username: Your WordPress admin username
- WordPress Application Password: Create this in WordPress under your user profile β Application Passwords
- SHB Tag to Watch: The tag that triggers auto-posting (e.g.,
thc) - WordPress Tags: Comma-separated tags to add to posts (e.g.,
interesting,thc,shb) - WordPress Categories: Comma-separated categories (e.g.,
Interesting stuff)
- Click Test Connection to verify your credentials
- Save settings
Once WordPress is configured and tested:
- Each bookmark on the dashboard will show a π€ (publish) button
- Hover over the button to check if the bookmark already exists in WordPress
- Click to publish the bookmark immediately
- The button will be greyed out if the bookmark is already published
- Private bookmarks CAN be manually published (manual publish works on all bookmarks, including private ones)
The sync script (scripts/shb_thc_to_wp.php) automatically posts new bookmarks with your watch tag to WordPress.
Features:
- Processes multiple bookmarks per run (catches up on backlog)
- Skips bookmarks that already exist in WordPress (checks by URL)
- Preserves original bookmark creation date in WordPress posts
- Uses settings from the database (no environment variables needed)
- Private bookmarks are NOT auto-posted (automatic sync only processes public bookmarks)
Scheduling Options:
-
Cron (if available):
*/2 * * * * /usr/bin/php /path/to/scripts/shb_thc_to_wp.php >>$HOME/shb_sync.log 2>&1 -
Control Panel Scheduled Tasks (Plesk, cPanel, Enhance, etc.):
- Use the terminal command shown in Settings
- Schedule it to run every 2-5 minutes
The script reads all settings from the database, so you don't need to set environment variables unless you want to override specific settings.
Free to use and modify for personal use.
See it in action: https://bookmarks.thoughton.co.uk
Tim Houghton - https://thoughton.co.uk