MarkTab replaces the Chrome new tab page with a visual bookmark dashboard, making local browser bookmarks easier to browse, search, and organize by user-created folders.
MarkTab
一个安静、快速、隐私友好的书签启动器。
MarkTab 把你的 Chrome 书签变成一个优雅、高效的书签启动器。打开新标签页即可在 1-2 个动作内找到目标网站。
主要功能:
- 搜索优先 — Spotlight 风格搜索面板,输入即搜,结果按书签/文件夹/网页搜索分组展示
- 按文件夹浏览 — 左侧文件夹导航 + 右侧书签网格卡片,支持文件夹内搜索过滤
- 首页分层 — Pinned 主入口(大卡片)> Recent 辅助(紧凑列表)> Folders 分类(胶囊按钮)
- 网页搜索 — 通过 Chrome Search API 使用浏览器默认搜索引擎,不自行选择或重定向
- 置顶常用书签 — 任何书签均可置顶,首页 Pinned 区域展示
- 隐藏/恢复分类 — 可在设置面板中切换文件夹可见性
- 主题切换 — Light / Dark / System 三套主题 + 森林绿单一强调色
- Favicon — 使用 Chrome 内置 favicon 服务,加载失败自动回退到首字母
- 弹出窗口 — 查看书签统计、打开新标签页、添加当前页面为书签
- 键盘驱动 —
//⌘K聚焦搜索,↑↓导航,Enter打开,Esc关闭 - 隐私优先 — 不向第三方发送书签标题、URL、域名或设置数据
- Manifest V3,无框架依赖
Productivity
Chinese Simplified English
Short description:
A calm, fast, privacy-friendly bookmark launcher.
Detailed description:
MarkTab turns your Chrome bookmarks into an elegant, efficient bookmark launcher. Open a new tab and find the site you need in one or two actions.
Key features:
- Search first — Spotlight-style search panel with grouped bookmark, folder, and web search results
- Folder browsing — Sidebar folder navigation with bookmark grid cards and in-folder filtering
- Layered home page — Pinned primary shortcuts, Recent quick access, and Folders for browsing
- Web search — Uses the Chrome Search API with the browser's default search engine
- Pinned bookmarks — Pin any bookmark and keep it on the home page
- Bilingual UI — Supports English and Simplified Chinese through Chrome i18n
- Favicon support — Uses Chrome's built-in favicon service with letter fallback
- Popup actions — View bookmark stats, open a new tab, add the current page, or manage bookmarks
- Keyboard driven —
//Ctrl or Cmd + Kopens search, arrow keys navigate,Enteropens,Esccloses - Privacy first — Bookmark titles, URLs, domains, and settings are not sent to developer servers
- Manifest V3, framework-free
| Permission | Justification |
|---|---|
bookmarks |
Required to read the user's bookmark tree, display bookmarks on the new tab page, count bookmarks/folders, and create a bookmark when the user clicks “添加当前页面”. |
favicon |
Required to display bookmark favicons through Chrome's built-in favicon service. |
search |
Required only when the user actively submits a web search from the new tab page. It uses Chrome's default search provider through the Chrome Search API. |
storage |
Required to save user preferences such as hidden folder IDs, pinned bookmark URLs, selected theme, and folder navigation collapsed state. |
activeTab |
Required only when the user opens the popup and clicks “添加当前页面”; it allows the extension to read the active tab title and URL for bookmark creation. |
- Single purpose: Display and search local Chrome bookmarks on a replacement new tab page.
- Remote code: No remote code is loaded or executed.
- Data collection: The extension handles bookmark data locally to provide its core functionality. Bookmark data is not sent to developer servers.
- Data sharing/sale: No user data is sold or shared for advertising or unrelated purposes.
- Privacy policy URL: Publish
PRIVACY_POLICY.mdcontent to a public URL before submission and use that URL in the dashboard.
- Start with an item that is already published in the Chrome Web Store, has two-step verification enabled for its publisher account, and has a review-ready listing and privacy disclosures.
- In Google Cloud, enable the Chrome Web Store API, configure the OAuth consent screen, and create a Desktop app OAuth client. The helper uses that client with a temporary loopback callback on
127.0.0.1. - If the OAuth consent app uses the External user type and remains in Testing, add the same Google developer account that will perform authorization—the item owner or an account with publisher access—as a Test user before authorizing.
- Google limits refresh tokens to seven days for External consent apps in Testing when the
chromewebstorescope is requested. For durable CI, move the consent app to In production before generating the finalCWS_REFRESH_TOKEN. If Testing is intentional, rerunnpm run cws:authand rotate the GitHub secret before each seven-day expiry. - Find the extension's item ID in the Chrome Web Store Developer Dashboard or in its listing URL. Store that value as
CWS_ITEM_ID; do not substitute an invented or example ID. - Rotate any client secret, refresh token, or other credential that has been exposed through an uncontrolled channel before configuring automation.
Configure these GitHub Actions secrets, with these exact names:
CWS_CLIENT_IDCWS_CLIENT_SECRETCWS_REFRESH_TOKENCWS_ITEM_ID
From PowerShell, let GitHub CLI prompt interactively for the three known values so they do not appear in shell history:
gh secret set CWS_CLIENT_ID
gh secret set CWS_CLIENT_SECRET
gh secret set CWS_ITEM_IDThen provide the OAuth client credentials to the local authorization helper without placing private values in the command line:
$env:CWS_CLIENT_ID = Read-Host "OAuth client ID"
$secureClientSecret = Read-Host "OAuth client secret" -AsSecureString
$secretPointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureClientSecret)
try {
$env:CWS_CLIENT_SECRET = [Runtime.InteropServices.Marshal]::PtrToStringBSTR($secretPointer)
npm run cws:auth
} finally {
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($secretPointer)
Remove-Item Env:CWS_CLIENT_ID -ErrorAction SilentlyContinue
Remove-Item Env:CWS_CLIENT_SECRET -ErrorAction SilentlyContinue
}npm run cws:auth opens the browser for OAuth authorization. Sign in with the Google developer account that owns, or has publisher access to, the target Chrome Web Store item; this may be different from the account that owns the Google Cloud project. After the loopback callback completes, the helper pipes the returned refresh token directly to gh secret set CWS_REFRESH_TOKEN over standard input. It does not print or store the token locally. Never commit credentials or paste them into issues, pull requests, logs, or chat.
For routine releases, follow Automated releases (maintainers). The pushed vX.Y.Z tag triggers deterministic packaging, a draft GitHub Release, and Chrome Web Store plus Edge Add-ons submissions; the GitHub Release becomes public only after both store APIs accept their submissions.
The publisher currently uses the Chrome Web Store Publish API V1. Google has deprecated V1 and documents support only through October 15, 2026, so migrate this workflow to V2 before that date.
To retry a failed release, open Actions → Release → Run workflow, enter the existing vX.Y.Z tag, and run it. The workflow checks out that exact tag, rebuilds the deterministic ZIP, creates or reuses a draft release, and replaces any same-named ZIP asset. A failure after draft creation leaves the GitHub Release as a draft; failures during version checks, tests, validation, or packaging can occur before any release exists.
If the final Publish GitHub Release step failed, first confirm in both developer dashboards that Chrome Web Store and Edge Add-ons accepted their review submissions. Then run the same tag again and enable publish_github_release_only. This recovery mode requires an existing draft, skips both store uploads and submissions entirely, and retries only publishing the GitHub Release. Do not enable it when either store submission failed or remains ambiguous.
If the remote Chrome Web Store state is ambiguous, inspect the item in the Developer Dashboard before retrying. Never invent a replacement version or move the existing tag. Chrome Web Store review is asynchronous: monitor it manually in the Developer Dashboard and respond to review feedback there.
- Run
npm run validate. - Run
npm run packageand inspect the generated zip indist/; the automated tag workflow performs the upload and store submission. - Optional: run
npm run inspect:zipto review the package contents. - Confirm the zip only includes
manifest.json,newtab.html,newtab.js,styles.css,popup.html,popup.js, and required icons. - Confirm
_locales/en/messages.jsonand_locales/zh_CN/messages.jsonare included in the zip. - Do not include
.DS_Store, icon generation helper pages, source drafts, store screenshots, or local caches. - Test by loading the unpacked extension from
chrome://extensions. - Verify:
- Home page: search, Pinned/Recent/Folders sections render correctly
- Search panel: Spotlight overlay opens via click,
/, and⌘K; results group by bookmarks/folders/web; keyboard navigation works - Folder view: sidebar navigation, bookmark grid, inline search filtering
- Settings: theme switching and folder visibility toggles
- Popup: statistics, open new tab, add current page, manage bookmarks
- Verify all settings persist after reload (theme, hidden folders, pinned bookmarks).
- Verify "添加当前页面" only reads the active tab after the user clicks the popup action.
- Run
npm run screenshotsto refresh store screenshots, then review the files instore-assets/. - Confirm listing claims match the extension behavior.
Future coding agents should follow AGENTS.md: keep the extension single-purpose, avoid remote executable code, keep permissions minimal, and update privacy/store documentation whenever data handling or permissions change.