Skip to content

syf2211/ai-html-translator-safari

Repository files navigation

AI HTML Translator Safari

中文说明

Safari-first AI translation for long web pages, local HTML reports, and research PDFs. Bring your own OpenAI-compatible API key, configure once, then translate from Safari with one click.

The project has two Safari paths:

  • Userscripts mode: the practical no-Apple-Developer path. Users install the free Userscripts app from the App Store, add one .user.js file, configure API settings once, and get an in-page floating translator on normal web pages.
  • Native Safari extension mode: a macOS containing app plus Safari WebExtension. This is the strongest long-term Safari integration, but public near-one-click distribution needs Developer ID signing and notarization.

Why this exists

Most browser translation extensions are built around Chrome and Firefox first. Safari users often get a weaker path: manual conversion, missing local-file support, or no clean way to use their own AI provider.

AI HTML Translator Safari focuses on a narrower but useful workflow:

  • Userscripts mode that works without an Apple Developer account
  • Safari-native packaging through an Xcode macOS containing app
  • file:// local HTML translation for generated reports and dataset viewers
  • PDF text extraction through bundled PDF.js
  • OpenAI-compatible API support, including DeepSeek-compatible endpoints
  • BYOK configuration stored locally
  • Chunked translation with failed-batch retry
  • A floating control that can be collapsed or dragged away when it covers UI

Current status

The recommended no-Apple-Developer path is userscript/ai-html-translator.user.js. It gives ordinary Safari users a close-to-extension experience on normal web pages: install Userscripts once, install this script once, save API settings once, then translate from the floating page control.

The native Safari extension is also kept in the repository. It remains the best path for local HTML and text-based PDF workflows, but public direct-download distribution requires a signed and notarized macOS app.

Similar projects and positioning

The translation extension space is crowded, but Safari-native open-source AI translation is still a narrower lane.

  • Immersive Translate supports Safari and has strong product coverage across web pages, PDFs, video subtitles, and many providers. It is the benchmark for mass-market translation UX, but it is not positioned as a small Safari-first open-source BYOK codebase.
  • Several open-source translator extensions target Chrome or Firefox and call Google, Bing, DeepL, OpenAI, or other APIs. Safari support is commonly absent, experimental, or requires manual conversion.
  • This project should not compete as a general translation suite. Its strongest positioning is: Safari-native, BYOK, local HTML/PDF, research and data-review workflows.

See docs/RESEARCH.md for the Safari distribution research, competitor notes, and implementation complexity assessment.

How it works

The project has three layers.

The no-Apple-Developer Userscript lives in userscript/.

  • ai-html-translator.user.js injects the floating UI directly through the Userscripts Safari extension.
  • It stores API settings with GM.setValue / GM.getValue.
  • It calls OpenAI-compatible /chat/completions endpoints with GM.xmlHttpRequest, which avoids normal webpage CORS limits.
  • It supports draggable and collapsible in-page controls, restore original text, failed-batch retry, and one-time configuration.

The WebExtension source lives in ai-html-translator-extension/.

  • manifest.json declares the Safari/Browser extension permissions.
  • content.js injects the floating UI, extracts visible text from the page, batches text, applies translations back into the DOM, restores original text, and handles PDF translation panels.
  • background.js owns settings and calls the configured OpenAI-compatible /chat/completions endpoint.
  • popup.html, popup.js, and popup.css provide the configuration page.
  • pdf.min.js, pdf.worker.min.js, and pdf-page.js extract text from PDFs.

The Safari containing app lives in AIHTMLTranslatorSafari/.

Safari requires a macOS app wrapper for WebExtensions. The Xcode project embeds the WebExtension resources into a .appex, then the containing app registers it with Safari.

Translation flow:

  1. The content script finds visible user-facing text nodes and selected attributes such as alt, title, aria-label, placeholder, and button value.
  2. Duplicate strings are collapsed so identical text is translated once.
  3. Text is split by batchChars and batchItems.
  4. Each batch is sent to the background script.
  5. The background script sends a strict JSON translation request to the configured provider.
  6. Returned items are matched by id and written back into the page.
  7. Failed batches are kept in a retry queue and can be retried without retranslating the whole page.

PDF flow:

  1. The extension detects a PDF URL or embedded PDF.
  2. PDF.js extracts text page by page.
  3. Extracted text is split into translation chunks.
  4. Translated chunks are shown in a right-side PDF panel.

Install for users

Recommended: Userscripts mode, no Apple Developer account

This is the easiest path today and does not require this project to publish a signed macOS app.

  1. Install Userscripts from the Mac App Store.
  2. Open Userscripts.app once from Applications. With Userscripts 4.x, the default scripts directory is normally created automatically. If the app asks for first-use setup or a save location, choose the default location or another ordinary folder you will keep.
  3. Open Safari and enable Userscripts in Safari > Settings > Extensions.
  4. Allow Userscripts to access the websites you want to translate. For the simplest setup, choose Always Allow for your common sites or all websites.
  5. Install ai-html-translator.user.js from this repository. If Safari only shows source code, click the Userscripts toolbar icon and use the install prompt, usually shown near the bottom of the popup. If there is still no prompt, save the file as ai-html-translator.user.js, place it in the save location shown in Userscripts settings, then open the Userscripts popup once so it refreshes the script list.
  6. Refresh the target web page.
  7. Click the floating AI 翻译 button.
  8. Open , fill Base URL, API Key, Model, and target language, then click 保存配置.

After that, normal web pages translate with one click. The floating control can be dragged, collapsed to AI, restored, and used to retry failed batches.

See docs/USER_INSTALL.md for a Chinese step-by-step guide.

Optional: signed native Safari extension

Download the latest signed release from the project's GitHub Releases page, then:

  1. Download AIHTMLTranslatorSafari-<version>-macOS.dmg.
  2. Open the DMG and drag AIHTMLTranslatorSafari.app to Applications.
  3. Open AIHTMLTranslatorSafari.app once.
  4. Click 打开 Safari 扩展设置.
  5. Enable AI HTML Translator.
  6. Allow the websites you want. To translate local HTML or PDF files, allow local file access when Safari asks.

After that, use the toolbar icon or the page floating button.

Local developer install

You need macOS and full Xcode.

  1. Open AIHTMLTranslatorSafari/AIHTMLTranslatorSafari.xcodeproj.
  2. Select the AIHTMLTranslatorSafari scheme.
  3. In Signing & Capabilities, choose your Apple Development Team for both the app and extension targets.
  4. Run the app once from Xcode.
  5. Enable the extension in Safari > Settings > Extensions.

You can also build from the command line:

DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer xcodebuild \
  -project AIHTMLTranslatorSafari/AIHTMLTranslatorSafari.xcodeproj \
  -scheme AIHTMLTranslatorSafari \
  -configuration Release \
  -destination 'platform=macOS' \
  build

Configure once

Open the extension popup from Safari and fill:

  • Base URL: for example https://api.deepseek.com
  • API Key: your provider key
  • Model: for DeepSeek's low-cost default, use deepseek-v4-flash; otherwise use the model name accepted by your provider
  • Target language: for example 简体中文

Click Test API. If it succeeds, click Save.

The key is stored in browser extension local storage on your machine. The source code does not include any default API key.

In Userscripts mode, the same settings are saved with Userscripts local storage. The script also does not include any default API key.

Use

  • Click AI 翻译 on the floating control to translate the current page.
  • Click the Safari toolbar extension icon and use 翻译当前页面.
  • Click 原文 to restore the page.
  • Click 重试失败(n) if a long page has failed batches.
  • Click × to collapse the floating control into a small AI button.
  • Drag the handle on the floating control if it covers page UI.

In native extension mode, PDFs create a side panel with extracted translation text. It does not rewrite the PDF canvas itself. Userscripts mode focuses on normal http and https web pages; Safari file:// pages and built-in PDF viewer pages are less reliable through user scripts.

If the floating control does not appear, check that Userscripts.app has been opened once, the Safari extension is enabled, the current website is allowed, the script is installed and enabled in Userscripts, and the page was refreshed after installation.

Permissions

The extension asks for:

  • activeTab: operate on the current tab after user action.
  • scripting: inject the content script when Safari has not loaded it yet.
  • storage: save API settings locally.
  • tabs: find the active tab for popup actions.
  • <all_urls> and file:///*: support normal web pages, local HTML, and PDFs.

Privacy

The extension sends extracted page text to the API endpoint you configure. Images, scripts, styles, and form inputs are not intentionally sent. PDF text is extracted locally with PDF.js, then sent as text chunks for translation.

Do not configure an API provider you do not trust for confidential pages.

Userscripts mode sends the same kind of extracted page text through GM.xmlHttpRequest to the provider you configure. Your API key is stored locally by Userscripts.

Release checklist

Before publishing a GitHub release:

  1. Ensure no API keys or personal signing files are present.
  2. Build the macOS app in Release mode.
  3. Sign with Developer ID Application or distribute via Mac App Store.
  4. Notarize the .app or .dmg for direct download distribution.
  5. Attach the signed archive to GitHub Releases.
  6. Document the exact macOS and Safari versions tested.

Do not publish build/, .p12, .key, .crt, .dSYM, .app, or .appex files to the source repository.

Maintainers can use scripts/check-release-readiness.sh and scripts/package-release.sh. See docs/MAINTAINER_RELEASE.md for the complete signing, notarization, and GitHub Release workflow.

FAQ

Does it support Safari?

Yes. Safari is the primary target. The repository includes an Xcode containing app and Safari WebExtension target.

Can users install it with one click?

Userscripts mode is the closest no-Apple-Developer answer: install Userscripts, install one .user.js, configure once, then click the floating control. The native Safari extension can be near-one-click only after Developer ID signing and notarization or Mac App Store distribution.

Why keep Userscripts mode and native extension mode?

Userscripts mode avoids the Apple Developer account and signing barrier. Native extension mode gives stronger Safari integration for local files and PDFs once the release path is available.

Does it support Chrome or Firefox?

The extension code is WebExtension-style JavaScript, but the product focus is Safari. Chrome/Edge can load ai-html-translator-extension/ as an unpacked extension for development.

Why not preserve PDF layout?

Safari renders PDFs as a viewer/canvas-like document. The extension extracts text and shows a side translation panel. Preserving PDF layout would require a separate PDF rendering/reconstruction pipeline.

Which API providers work?

Any provider compatible enough with OpenAI-style /chat/completions can work. DeepSeek-compatible endpoints are the default examples. Some providers do not support response_format or provider-specific thinking options; turn those off in advanced settings if needed.

What should I do if translation fails midway?

Use 重试失败(n). Long pages are translated in batches, and failed batches do not discard successful translations.

License

MIT. See LICENSE.

Bundled PDF.js files are covered by Apache License 2.0. See THIRD_PARTY_NOTICES.md.

About

No description, website, or topics provided.

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors