A bookmark manager built with Next.js and backed by a Notion database. The app lets you save links, organize them with tags, pin important items, and track visits from a responsive interface.
This project started from the Frontend Mentor bookmark manager challenge, but the current implementation is adapted to use Notion as the data source instead of a local mock dataset.
The application reads and writes bookmarks directly to a Notion database through the Notion API. Bookmarks are displayed in a card-based layout with tag filtering, optimistic pinning, visit tracking, and quick actions for opening or copying links.
- View bookmarks from a Notion database
- Add bookmarks with title, description, website URL, and tags
- Filter bookmarks by one or multiple tags
- Pin and unpin bookmarks
- Open bookmarked links in a new tab
- Track visit count and last visited date when a link is opened
- Copy bookmark URLs to the clipboard
- Show favicon, domain, tags, creation date, and usage metadata for each bookmark
- Use a responsive sidebar layout with a mobile menu
- Display loading skeletons while bookmark data is being fetched
- Browse archived bookmarks on a dedicated page
- Next.js 16 with the App Router
- React 19
- TypeScript
- Tailwind CSS v4
- Redux Toolkit and React Redux
- React Hook Form with Zod validation
- Notion API via
@notionhq/client - Sonner for toast notifications
npm installCreate a .env.local file in the project root with:
NOTION_API_KEY=your_notion_integration_secret
NOTION_DATABASE_ID=your_notion_database_idImportant:
NOTION_DATABASE_IDmust be the database ID from the Notion URL path, not thev=view identifier.- The Notion database must be shared with the integration used by
NOTION_API_KEY.
npm run devThen open http://localhost:3000.
The app expects the connected Notion database to contain these properties:
| Property | Type |
|---|---|
Title |
Title |
URL |
URL |
Description |
Rich text |
Tags |
Multi-select |
Pinned |
Checkbox |
Archived |
Checkbox |
VisitCount |
Number |
LastVisited |
Date |
CreatedTime |
Created time |
Behavior notes:
- Archived entries are excluded from tag counts.
- Bookmarks are sorted with pinned items first, then by creation date.
- Favicons are derived from each bookmark URL at render time.
npm run devstarts the development servernpm run buildcreates a production buildnpm run startruns the production servernpm run lintruns ESLintnpm run formatformats the codebase with Prettiernpm run format:checkchecks formatting without writing changes
The codebase already includes some UI affordances that are not fully wired yet:
- The search input is present in the header, but bookmark searching by title is not connected to the data query yet.
- Dark mode styles exist in the UI, but a theme toggle is not currently implemented.
