---
title: "Chrome Extension 開發實戰：從零開始打造內容合規檢查工具，整合 Keycloak 登入到上架全攻略"
description: "完整分享 Chrome Extension 開發流程，包含 Manifest V3 架構、整合 Keycloak SSO 登入、產品導流策略設計，以及如何上架到 Chrome 線上應用程式商店。"
canonical_url: "https://blog.markkulab.net/post/chrome-extension-content-compliance-marketing"
author: "Mark Ku"
author_url: "https://blog.markkulab.net/author/mark-ku"
site: "Mark Ku's Blog"
date_published: "2026-01-31 10:00:00 +0800"
category: "Frontend"
tags: ["chrome-extension", "marketing", "lead-generation", "manifest-v3", "keycloak", "oauth2"]
language: "zh-TW"
license: "CC BY 4.0"
license_url: "https://creativecommons.org/licenses/by/4.0/"
attribution: "轉載或引用請註明作者並附上原文連結"
---

# Chrome Extension 開發實戰：從零開始打造內容合規檢查工具，整合 Keycloak 登入到上架全攻略

> **TL;DR** — 歡迎來到 Mark 的 Tech Insights，我是主持人璦廷。你是否想過，瀏覽器擴充功能不只是實用工具，還能成為絕佳的產品導流神器？今天，我們將帶您從零開始，探索如何開發一款內容合規檢查的 Chrome 擴充功能。 讓我們來看看實際的應用場景。想像一下，行銷人員在發布貼文前，只要選取網頁文字按右鍵，就能快速檢查文案是否觸犯法規，甚至支援圖片識別與截圖檢查，能大幅降低違規風險。 在技術層面，這個重點值得注意。專案全面採用最新的 Manifest V3 架構，以 Service Worker 提升執行效率與安全性。此外，為了實現單一登入，系統整合了開源的 Keycloak，並搭配專屬的安全機制，確保登入過程滴水不漏。 開發工具的同時，我們也融入了產品導流策略。透過解鎖完整建議的行動呼籲設計，使用者能獲得有價值的分析報告，團隊也能藉此收集潛在客戶名單，創造雙贏的價值交換。 總結來說，擴充功能不僅能建立品牌認知，更能有效降低獲客成本。如果您正在思考如何為產品開創新的曝光管道，不妨評估看看，您的核心服務是否也能化身為使用者瀏覽器上的得力助手呢？

## 前言

今年我們團隊打算在 Chrome 瀏覽器推出一款「網頁內容檢核」的擴充功能，主要目的是增加產品曝光機會，同時也能為使用者提供實用的工具。

這篇文章+將完整分享：
1. **Chrome Extension 開發重點** - 架構設計與必備知識
2. **整合 Keycloak 登入** - 如何在擴充功能中實現 SSO 單一登入
3. **產品導流策略** - 如何將免費工具轉換為付費客戶
4. **上架 Chrome 商店** - 從打包到審核的完整流程

## 產品定位與目標用戶

這款擴充功能的主要目標用戶是**行銷小編與社群經營者**。他們在發文前，常常需要確認內容是否符合相關法規要求，避免廣告文案觸犯法規而遭到處罰。

### 使用情境

想像一下這個場景：

> 小編準備在 Facebook 發布一則保健食品的促銷貼文，在正式發布前，她想確認文案中是否有違規用詞。這時候，她只需要選取文字，右鍵點擊，就能快速檢查內容是否合規。

![合規檢查操作示範](https://blog.markkulab.net/content/markku/posts/chrome-extension-content-compliance-marketing/images/extension-compliance-check-demo.png)

## 核心功能設計

### 右鍵選單功能

使用者在網頁上選取文字後，可透過右鍵選單快速進行檢查：

```mermaid
---
title: 右鍵選單的四個檢查入口
---
flowchart LR
  M["🖱️ 右鍵選單"] --> C["📋 複製"]
  M --> S["🔍 搜尋"]
  M --> G["🛡️ 廣告合規檢查<br/>本擴充功能加上去的項目"]
  G --> T["📝 檢查選取文字"]
  G --> L["🔗 檢查連結內容"]
  G --> I["🖼️ 檢查圖片文字"]
  G --> P["✂️ 截圖檢查"]
```

### 四種檢查模式

1. **📝 檢查選取文字** - 直接檢查選取的文字內容
2. **🔗 檢查連結內容** - 抓取網頁內容進行分析
3. **🖼️ 檢查圖片文字** - 透過 OCR 識別圖片中的文字
4. **✂️ 截圖檢查** - 截取畫面區域進行文字識別與檢查

## 技術架構

這個專案採用 **Manifest V3** 架構開發，主要技術組成如下：

```
chrome-extension/
├── manifest.json          # 插件配置檔（Manifest V3）
├── background.js          # Service Worker
├── content.js             # 內容腳本
├── config.js              # 集中設定檔
│
├── auth/                  # 認證模組（Keycloak 整合）
│   ├── auth-config.js     # 認證設定
│   ├── auth-service.js    # 登入邏輯
│   ├── auth.html          # 登入頁面
│   └── auth.js            # 登入 UI 控制
│
├── core/                  # 核心模組
│   ├── utils.js           # 共用工具
│   ├── risk-levels.js     # 風險等級定義
│   └── api-client.js      # API 呼叫封裝
│
├── handlers/              # 功能處理器
│   ├── text-handler.js    # 文字檢查
│   ├── link-handler.js    # 連結檢查
│   ├── image-handler.js   # 圖片 OCR
│   └── screenshot-handler.js # 截圖檢查
│
├── ui/                    # UI 元件
│   ├── loading.js         # 載入動畫
│   ├── dialog.js          # 對話框
│   ├── result-panel.js    # 結果面板
│   └── styles.css         # 樣式
│
├── popup/                 # Popup 頁面
│   ├── popup.html
│   ├── popup.css
│   └── popup.js
│
└── options/               # 設定頁面
    ├── options.html
    ├── options.css
    └── options.js
```

---

## Chrome Extension 開發重點

如果你是第一次開發 Chrome 擴充功能，以下是幾個必須了解的核心概念：

### 什麼是 Chrome Extension？

簡單來說，Chrome Extension 就是一個**跑在瀏覽器裡的小程式**，可以：

- 在網頁上加入新功能（如右鍵選單、浮動按鈕）
- 讀取或修改網頁內容
- 與外部 API 溝通
- 儲存使用者設定

### Manifest V3 vs V2：一定要用新版！

Chrome 已經強制要求新的擴充功能使用 **Manifest V3**，2024 年起 V2 將逐步淘汰。

| 差異 | Manifest V2（舊版） | Manifest V3（新版） |
|------|-------------------|-------------------|
| 背景執行 | Background Page（常駐） | Service Worker（按需啟動） |
| 權限管理 | 較寬鬆 | 更嚴格，需明確宣告 |
| 安全性 | 一般 | 更高，限制 remote code |
| 上架 | 已停止接受 | 必須使用 |

### 五大核心檔案

開發 Chrome Extension 一定會用到這些檔案：

```mermaid
---
title: Manifest V3 的五個核心檔案
---
flowchart TB
  MF["manifest.json（必備）<br/>擴充功能的身分證<br/>定義名稱、權限、檔案位置"]
  MF --> BG["background.js<br/>Service Worker"]
  MF --> CT["content.js<br/>Content Script"]
  MF --> PP["popup.html<br/>點擊圖示時彈出的小視窗"]
  MF --> OP["options.html<br/>使用者調整設定的頁面"]
  BG --> BGD["背景執行：監聽事件、呼叫 API<br/>不能直接操作網頁 DOM"]
  CT --> CTD["注入網頁執行：可操作 DOM<br/>讀取網頁內容、插入 UI 元素"]
```

### manifest.json 設定範例

這是擴充功能最重要的檔案，告訴 Chrome 這個擴充功能需要什麼權限：

```json
{
  "manifest_version": 3,
  "name": "快合規快篩",
  "version": "1.1.0",
  "description": "圈選任何文字，快速檢查是否符合廣告法規",
  
  "permissions": [
    "contextMenus",    // 右鍵選單
    "activeTab",       // 存取當前分頁
    "storage",         // 儲存資料
    "notifications",   // 顯示通知
    "scripting",       // 動態注入腳本
    "identity"         // OAuth 登入
  ],
  
  "host_permissions": [
    "https://api.textcomply.com/*",  // API 網址
    "https://sso.example.com/*"       // SSO 登入網址
  ],
  
  "background": {
    "service_worker": "background.js"
  },
  
  "action": {
    "default_popup": "popup/popup.html",
    "default_icon": "logo/icon128.png"
  }
}
```

### 各元件如何溝通？

Chrome Extension 的各個部分是「隔離」的，需要透過 **Message Passing** 溝通：

```mermaid
---
title: Content Script 與 Background 的職責分工
---
flowchart LR
  CS["Content Script<br/>跑在網頁裡"]
  BG["Background<br/>Service Worker"]
  CS <-->|"chrome.runtime.sendMessage()<br/>chrome.runtime.onMessage"| BG
  CS --> CSD["操作網頁 DOM<br/>注入 UI 元素"]
  BG --> BGD["呼叫外部 API<br/>處理登入認證"]
```

程式碼範例：

```javascript
// content.js - 發送訊息給 background
chrome.runtime.sendMessage(
  { action: 'checkText', text: '選取的文字內容' },
  (response) => {
    console.log('檢查結果：', response);
  }
);

// background.js - 接收並處理訊息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'checkText') {
    // 呼叫 API 檢查文字
    checkTextApi(message.text).then(result => {
      sendResponse(result);
    });
    return true; // 表示會非同步回應
  }
});
```

---

## 整合 Keycloak SSO 登入

如果你的產品需要使用者登入，可以整合 **Keycloak**（或其他 OAuth2 / OIDC 提供者）來實現單一登入。

![擴充功能登入頁面](https://blog.markkulab.net/content/markku/posts/chrome-extension-content-compliance-marketing/images/extension-login-page.png)
![Login](https://blog.markkulab.net/content/markku/posts/chrome-extension-content-compliance-marketing/images/extension-login-popup.jpg)

### 為什麼選 Keycloak？

- ✅ **開源免費** - 不用付授權費
- ✅ **支援多種登入方式** - 帳密、Google、GitHub、Facebook...
- ✅ **標準協定** - 使用 OAuth2 / OpenID Connect
- ✅ **企業級功能** - 角色管理、多租戶、MFA 等

### 整合流程概覽

```mermaid
---
title: Chrome Extension 整合 Keycloak 的登入流程
---
sequenceDiagram
  actor U as 使用者
  participant E as 擴充功能
  participant K as Keycloak
  participant A as 後端 API

  U->>E: 點擊「登入」
  E->>K: 開啟 Keycloak 登入頁面
  U->>K: 輸入帳密，或選擇第三方登入
  K-->>E: 驗證成功，回傳 Authorization Code
  E->>K: 用 Code 換取 Access Token
  K-->>E: 回傳 Access Token
  Note over E: 儲存 Token
  E->>A: 後續 API 呼叫都帶上 Token
```

### 設定 Keycloak Client

在 Keycloak 管理後台建立 Client：

```
Client ID: chrome-extension
Client Protocol: openid-connect
Access Type: public (擴充功能無法保密 client_secret)
Valid Redirect URIs: https://<extension-id>.chromiumapp.org/*
Web Origins: *
```

### PKCE 安全機制（重要！）

因為 Chrome Extension 是「公開客戶端」（無法安全儲存 client_secret），必須使用 **PKCE** 來增加安全性：

```javascript
// 1. 產生隨機的 code_verifier
function generateRandomString(length = 64) {
  const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
  const array = new Uint8Array(length);
  crypto.getRandomValues(array);
  return Array.from(array, (byte) => charset[byte % charset.length]).join('');
}

// 2. 用 code_verifier 產生 code_challenge
async function generateCodeChallenge(codeVerifier) {
  const encoder = new TextEncoder();
  const data = encoder.encode(codeVerifier);
  const hash = await crypto.subtle.digest('SHA-256', data);
  
  // Base64 URL 編碼
  const bytes = new Uint8Array(hash);
  let binary = '';
  bytes.forEach(byte => binary += String.fromCharCode(byte));
  return btoa(binary)
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
}
```

### 發起登入請求

```javascript
async function loginWithKeycloak() {
  // 1. 產生 PKCE 參數
  const codeVerifier = generateRandomString(64);
  const codeChallenge = await generateCodeChallenge(codeVerifier);
  const state = generateRandomString(32);
  
  // 2. 儲存 verifier（稍後換 token 時需要）
  await chrome.storage.local.set({ codeVerifier, state });
  
  // 3. 組合登入 URL
  const authUrl = new URL('https://sso.example.com/realms/myrealm/protocol/openid-connect/auth');
  authUrl.searchParams.set('client_id', 'chrome-extension');
  authUrl.searchParams.set('redirect_uri', chrome.identity.getRedirectURL());
  authUrl.searchParams.set('response_type', 'code');
  authUrl.searchParams.set('scope', 'openid profile email');
  authUrl.searchParams.set('code_challenge', codeChallenge);
  authUrl.searchParams.set('code_challenge_method', 'S256');
  authUrl.searchParams.set('state', state);
  
  // 4. 開啟登入視窗
  chrome.identity.launchWebAuthFlow(
    { url: authUrl.toString(), interactive: true },
    handleAuthCallback
  );
}
```

### 換取 Access Token

```javascript
async function exchangeCodeForToken(code) {
  const { codeVerifier } = await chrome.storage.local.get('codeVerifier');
  
  const response = await fetch(
    'https://sso.example.com/realms/myrealm/protocol/openid-connect/token',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({
        grant_type: 'authorization_code',
        client_id: 'chrome-extension',
        code: code,
        redirect_uri: chrome.identity.getRedirectURL(),
        code_verifier: codeVerifier  // PKCE 驗證
      })
    }
  );
  
  const tokens = await response.json();
  
  // 儲存 token
  await chrome.storage.local.set({
    accessToken: tokens.access_token,
    refreshToken: tokens.refresh_token,
    expiresAt: Date.now() + (tokens.expires_in * 1000)
  });
  
  return tokens;
}
```

### Token 自動刷新

Access Token 通常幾分鐘就會過期，需要自動刷新：

```javascript
async function getValidToken() {
  const { accessToken, refreshToken, expiresAt } = 
    await chrome.storage.local.get(['accessToken', 'refreshToken', 'expiresAt']);
  
  // Token 還沒過期，直接使用
  if (expiresAt && Date.now() < expiresAt - 60000) {
    return accessToken;
  }
  
  // Token 即將過期，用 refresh_token 換新的
  if (refreshToken) {
    const newTokens = await refreshAccessToken(refreshToken);
    return newTokens.access_token;
  }
  
  // 沒有 token，需要重新登入
  return null;
}
```

---

## 導流策略設計

這才是這個專案最精華的部分 - **如何將免費工具的使用者轉換為潛在客戶**。

### 漏斗設計流程

```mermaid
---
title: 從免費工具到業務接觸的導流路徑
---
flowchart TD
  subgraph EXT["擴充功能內"]
    S1["1️⃣ 安裝擴充功能（免費）"] --> S2["2️⃣ 選取文字或截圖，發動檢查"]
    S2 --> S3["3️⃣ 等待 AI 模型回應<br/>等待期間輪播廣告"]
    S3 --> S4["4️⃣ 顯示基本檢查結果<br/>部分資訊隱藏"]
  end
  subgraph WEB["官網"]
    S5["5️⃣ 點擊「取得完整建議」導流至官網"] --> S6["6️⃣ 填寫 Email 解鎖完整報告"]
    S6 --> S7["7️⃣ 業務後續接觸與轉化"]
  end
  S4 --> S5
```

### 等待時間的價值

當使用者發起檢查請求後，因為需要等待 AI 模型回應（通常 3-5 秒），這段時間就是絕佳的廣告曝光時機！

```javascript
// config.js - 輪播設定
CAROUSEL_IMAGES: [
  'images/banner_square-1.png',
  'images/banner_square-2.png'
],
CAROUSEL_INTERVAL_MS: 3000,
```

我們在 Loading 畫面中嵌入圖片輪播，投放產品廣告或促銷訊息。

### 結果頁面的導流設計

檢查結果會顯示：
- ✅ 是否合規
- ⚠️ 違規項目數量
- 🔒 **部分資訊以模糊方式呈現**

關鍵設計：**違規說明和調整建議會顯示前 15 個字，其餘以「...」遮蔽**，引導使用者點擊解鎖。

```javascript
// 說明（違規原因）- 鎖定狀態
if (violation.explanations && violation.explanations.length > 0) {
  const expPreview = escapeHtml(violation.explanations[0]).substring(0, 15) + '...';
  html += `
    <a href="${ctaLink}" target="_blank" class="compliance-result__locked-block">
      <div class="compliance-result__locked-header">
        <p class="compliance-result__locked-label">📋 違規說明</p>
        <span class="compliance-result__locked-icon">🔒</span>
      </div>
      <p class="compliance-result__locked-text compliance-result__locked-text--blur">${expPreview}</p>
      <p class="compliance-result__locked-cta">立即體驗完整功能</p>
    </a>
  `;
}
```

### CTA 按鈕設計

在結果面板底部，我們放置了醒目的行動呼籲按鈕：

```javascript
// CTA 按鈕
html += `
  <div class="compliance-result__footer">
    <a href="${ctaLink}" target="_blank" class="compliance-result__cta-btn">
      🚀 使用產品取得完整建議
    </a>
  </div>
`;
```

## Lead Generation 機制

當使用者點擊「取得完整建議」按鈕，會被導向解鎖頁面：

### 解鎖流程

1. 使用者填寫 Email
2. 驗證 Email 有效性
3. 解鎖完整報告
4. **每組 Email 只能解鎖一篇報告**

這個設計的巧妙之處：

- ✅ 使用者獲得有價值的完整分析報告
- ✅ 我們獲得有效的潛在客戶名單
- ✅ 業務團隊可以後續進行接觸與轉化

## 安裝與使用

### 從 Chrome 線上應用程式商店安裝

使用者可以直接在 Chrome 線上應用程式商店搜尋並安裝這個擴充功能。

### 開發者模式安裝

如果你想自己部署類似的專案：

1. 開啟 Chrome → `chrome://extensions/`
2. 開啟「開發人員模式」
3. 點擊「載入未封裝項目」
4. 選取 `chrome-extension` 資料夾

### 使用方式

1. 在任何網頁上**選取文字**
2. 按下**右鍵**
3. 選擇「🛡️ 廣告合規檢查」
4. 選擇檢查類型
5. 等待結果顯示



## 開發心得與建議

### Manifest V3 的挑戰

Chrome 已經強制要求新的擴充功能使用 Manifest V3，這帶來了一些開發上的改變：

- Service Worker 取代了 Background Page
- 需要更明確地宣告權限
- Content Script 的注入方式有所改變

### 模組化設計

建議將功能拆分成獨立模組：

- `core/` - 核心邏輯
- `handlers/` - 各種檢查處理器
- `ui/` - UI 元件

這樣的設計讓程式碼更易於維護和擴展。

### API 設計考量

```javascript
// 集中設定檔
const CONFIG = {
  DEFAULT_API_ENDPOINT: 'https://your-api-endpoint.com',
  IMAGE_OCR_PATH: '/api/image/ocr',
  CREATE_AND_CHECK_PATH: '/api/TextContent/CreateAndCheck',
  MAX_RETRIES: 3,
  RETRY_DELAY: 1000,
};
```

建議將 API 端點設計為可配置，方便未來切換環境或更新服務。

## 成效預期

目前擴充功能尚未正式上架，以下為規劃階段的初期目標，待上架後將依實際數據持續調整：

| 指標 | 初期目標 |
|------|------|
| 擴充功能安裝數 | 500+ 次（上架後追蹤） |
| 每月活躍用戶 | 200 人以上 |
| Lead 轉換率 | 5–10% |
| 有效名單數 | 每月 10–50 筆 |

## 總結

Chrome Extension 不只是一個工具，更是一個絕佳的**產品導流渠道**。透過提供免費且實用的功能，我們能夠：

1. **建立品牌認知** - 使用者每天使用，自然記住產品
2. **收集潛在客戶** - 透過解鎖機制獲取有效名單
3. **降低獲客成本** - 相較於廣告投放，擴充功能的 CAC 更低
4. **提供價值交換** - 使用者獲得工具，我們獲得 Lead

如果你也在思考如何為產品創造新的曝光管道，Chrome Extension 絕對值得一試！

---

## 參考資源

- [Chrome Extension Manifest V3 官方文件](https://developer.chrome.com/docs/extensions/mv3/)
- [Chrome 線上應用程式商店開發者政策](https://developer.chrome.com/docs/webstore/program_policies/)

---

## 關於本文與作者

本文出自 [Mark Ku's Blog](https://blog.markkulab.net/post/chrome-extension-content-compliance-marketing)

授權條款： [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) — 轉載或引用請註明作者並附上原文連結

### 關於作者

**[Mark Ku](https://blog.markkulab.net/author/mark-ku)** — Software Solution Provider

- 10+ 年資深軟體工程師，現為 AI 應用 Builder
- 專注大型平台架構設計，從北美電商到AI SaaS訂閱收費系統
- 結合 AI Agent 與自動化，打造高效可演進的產品技術基礎

### 作者開發的免費工具

以下工具皆可免費使用：

- [免費 PDF 簽名工具](https://blog.markkulab.net/tools/pdf-sign): 線上 PDF 簽名工具，瀏覽器內完成手繪、打字、上傳簽名，可拖曳放置、縮放、下載。所有處理都在你的裝置完成，檔案不會上傳。
- [VS Code Refactory](https://blog.markkulab.net/tools/refactory): Refactory 是一款 VS Code 重構擴充套件：34 個重構動作、37 條 code smell 檢查、Code Health 儀表板、18 種語言、534 支測試。懂你的專案慣例：介面放哪、DI 註冊寫在哪、'use client' 該不該加；還會用 git 修改頻率 × 複雜度排出「該先修哪個檔案」，並一鍵把壞味道交給你自己電腦上的 Claude Code 修。免費使用，原始碼不離開你的機器。
- [DB-Kit 資料庫管理工具](https://blog.markkulab.net/tools/db-kit): DB-Kit 是一個用 Tauri + Rust + React 打造的輕量跨平台資料庫管理工具，用單一一致的介面同時管理 MySQL、MariaDB、PostgreSQL、SQL Server、Oracle、SQLite、MongoDB、Redis、Kafka、Elasticsearch 與 RabbitMQ 十一種資料來源：連線密碼以 OS keychain 加密、SSH Tunnel、完整 CRUD、視覺化查詢建構器、多結果集同時顯示、跨連線資料傳輸與比對同步、Excel / CSV 匯入匯出、執行計畫視覺化、ER 圖、排程備份、SQL 壓力測試（p50～p99 延遲百分位）、15 條規則的 SQL 審查、Kafka 訊息瀏覽與監控告警；繁中 / 英文雙語介面，內建 AI 助手（自然語言生成 SQL、AI 審查與調校建議）與命令列工具 dbk。免費開源（MIT），提供 Windows / macOS / Linux 安裝檔。
- [VS Code Super Mermaid](https://blog.markkulab.net/tools/super-mermaid): Super Mermaid 是一款 VS Code 擴充套件：開箱即用的漂亮 Mermaid 圖表，自動上色、即時預覽、滑鼠平移縮放、PNG / SVG 高解析匯出，內建 21 種範本與多種主題。免費開源（MIT）。
- [React Super Mermaid](https://blog.markkulab.net/tools/react-super-mermaid): react-super-mermaid 是一個開源 React 元件庫：一行 <MermaidViewer> 即可渲染漂亮的 Mermaid 圖表，內建 colorful / sketch 主題、平移縮放、圖內搜尋、SVG / PNG 高解析匯出。輕量、SSR 安全、完整 TypeScript 型別。免費開源（MIT）。
- [Jira / Confluence Super Mermaid](https://blog.markkulab.net/tools/jira-super-mermaid): Atlassian Forge app：在 Jira issue 與 Confluence 內文直接寫 Mermaid 語法，畫流程圖、時序圖、狀態機與甘特圖。11 種圖表、SVG / PNG 匯出、明暗主題、完整中日韓文字支援。取得 Runs on Atlassian 資格：圖表存在你自己的站台，app 不呼叫任何第三方服務。免費，即將上架 Atlassian Marketplace。
- [Mermaid 線上預覽](https://blog.markkulab.net/tools/mermaid-preview): 在瀏覽器裡寫 Mermaid、即時看圖，整張圖表壓進網址就能分享。免註冊、不上傳伺服器，相容 mermaid.live 的分享連結。
- [React Intl Phone Number](https://blog.markkulab.net/tools/react-intl-phone-number): react-intl-phone-number 是一個開源 React 元件：framework-agnostic、不依賴 antd，提供 E.164 進出、可搜尋國旗 / 國碼下拉、可配置驗證等級（strict / mobile-strict / loose）、可主題化 CSS 與 i18n，電話邏輯由 google-libphonenumber 驅動。輕量、完整 TypeScript 型別。免費開源（MIT）。
- [Uptime Kuma Cluster](https://blog.markkulab.net/tools/uptime-kuma-cluster): 把單機版 Uptime Kuma 改造成高可用叢集：OpenResty + Lua 智慧負載平衡、MariaDB 共享狀態、健康檢查與自動 Failover，附叢集管理 REST API，一行 Docker Compose 啟動。免費開源（MIT）。
- [特教專案](https://blog.markkulab.net/education): 為特殊教育學生製作的學習教材

### 每日 Podcast

- [Mark's Tech Insights 每日 AI 新鮮事](https://blog.markkulab.net/category/tech-news): 每日精選 AI 與科技趨勢，透過語音摘要快速掌握最新技術動態，涵蓋 AI 應用、軟體架構、DevOps 與工程實戰。 — RSS: https://blog.markkulab.net/feed.xml
- [AI股市蝦聊](https://blog.markkulab.net/category/ai-stock-chat): 每個交易日用 AI 分析台股盤勢，以雙人對話聊當天的盤中觀察與隔日預測。 — RSS: https://blog.markkulab.net/ai-stock-chat/feed.xml
- [開源好物週報](https://blog.markkulab.net/category/open-source-weekly): 每週從 Hacker News、GitHub、Reddit 聲量雷達精選免費開源工具，以雙人對話聊解決什麼痛點與怎麼快速上手。 — RSS: https://blog.markkulab.net/open-source-weekly/feed.xml

### 電子報

[訂閱電子報](https://blog.markkulab.net/subscribe) — 第一時間收到新文章通知，無垃圾信、隨時可取消訂閱。
