feat: add X (Twitter) as a new search engine option#218
Conversation
- Add X search URL (x.com/search?q=) as engine10 in search.js - Add X logo SVG icon in index.html - Add dropdown item and radio button option for X in settings - Register xEngine in translationMap and elementsMap in languages.js - Add xEngine translation key to all 26 locale files - Update CHANGELOG.md Co-authored-by: Cursor <cursoragent@cursor.com>
📝 WalkthroughWalkthroughThis PR adds X (Twitter) as a supported search engine option. The implementation includes UI components, complete localization across 25+ languages, translation wiring, search URL routing, and changelog documentation. ChangesX Search Engine Addition
🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related PRs:
Suggested labels: Suggested reviewers:
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds X (Twitter) as an additional “search with” engine across the UI and translations.
Changes:
- Added an
engine10URL entry for X in the search engine URL map. - Extended language application logic and locale dictionaries with
xEngine/xEngineDD. - Updated the UI to include X in both the engine dropdown and the radio list, plus an SVG icon.
Reviewed changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/search.js | Adds X search URL mapping (engine10). |
| scripts/languages.js | Wires new localization keys into language application flow. |
| locales/*.js | Adds xEngine translation strings across multiple locales. |
| index.html | Adds X option to dropdown and engine list; introduces X SVG symbol. |
| CHANGELOG.md | Documents the newly added X search engine option. |
Comments suppressed due to low confidence (1)
index.html:865
- This introduces a second hidden
<svg>sprite block right after an existing one ends. To keep the DOM simpler and avoid duplicating hidden sprite containers, add the new<symbol id=\"x-engine-icon\">into the existing hidden<svg>sprite instead of creating a new<svg style=\"display: none;\">container.
</svg>
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <svg style="display: none;"> | ||
| <symbol id="x-engine-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> | ||
| <path style="transform: scale(0.75); transform-origin: center;" | ||
| d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" /> | ||
| </symbol> | ||
| </svg> |
| <svg style="display: none;"> | ||
| <symbol id="x-engine-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> | ||
| <path style="transform: scale(0.75); transform-origin: center;" | ||
| d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" /> | ||
| </symbol> | ||
| </svg> |
| "redditEngine", | ||
| "wikipediaEngine", | ||
| "quoraEngine", | ||
| "xEngine", | ||
| "chatGPT", | ||
| "gemini", | ||
| "copilot", |
| { id: "redditEngineDD", key: "redditEngine" }, | ||
| { id: "wikipediaEngineDD", key: "wikipediaEngine" }, | ||
| { id: "quoraEngineDD", key: "quoraEngine" }, | ||
| { id: "xEngineDD", key: "xEngine" }, | ||
| { id: "bookmarksHover", key: "bookmarksHeading" }, |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/search.js`:
- Around line 22-23: The new key "engine10" exposes that selection code slices
only the last character (e.g., id.slice(-1) or equivalent) to get the engine
number; locate the selection/restore logic that derives the numeric id from keys
like "engineX" (the code that references engine10) and replace the
single-character extraction with a full numeric parse (e.g., use a regex
/engine(\d+)/ and parseInt(match[1]) or parseInt(id.replace(/^engine/, ''))) so
the dropdown swap and restore use the full engine index rather than only the
last digit.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6880baee-0e6b-4e93-a42a-3eee3fee2204
📒 Files selected for processing (30)
CHANGELOG.mdindex.htmllocales/ar_SA.jslocales/bn.jslocales/cs.jslocales/de.jslocales/el.jslocales/en.jslocales/es.jslocales/fa.jslocales/fr.jslocales/hi.jslocales/hu.jslocales/idn.jslocales/it.jslocales/ja.jslocales/ko.jslocales/mr.jslocales/pl.jslocales/pt.jslocales/ru.jslocales/sv.jslocales/ta.jslocales/th.jslocales/uk.jslocales/uz.jslocales/zh.jslocales/zh_TW.jsscripts/languages.jsscripts/search.js
Fix single-character engine ID extraction that breaks engine10.
The previous code used charAt(value.length - 1) which only reads
the last character, causing engine10 to be parsed as "0" instead
of "10". Replace all 4 occurrences with replace("engine", "") to
correctly handle multi-digit engine numbers.
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
scripts/search.js (1)
370-377:⚠️ Potential issue | 🟠 Major | ⚡ Quick winGuard
storedSearchEnginebefore dereference in shortcut-switch flow.Line 374 and Line 376 can throw when
selectedSearchEngine-${activeSearchMode}is absent (nullfrom localStorage). Add a null guard before usingselectedRadioButton.checkedand.replace(...).Proposed fix
const storedSearchEngine = localStorage.getItem(`selectedSearchEngine-${activeSearchMode}`); + if (!storedSearchEngine) return; // Find the corresponding radio button const selectedRadioButton = document.querySelector(`input[name="search-engine"][value="${storedSearchEngine}"]`); - selectedRadioButton.checked = true; + if (!selectedRadioButton) return; + selectedRadioButton.checked = true; const storedSearchEngineSN = storedSearchEngine.replace("engine", "");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/search.js` around lines 370 - 377, storedSearchEngine can be null when localStorage lacks selectedSearchEngine-${activeSearchMode}, so guard its use before dereferencing: check that storedSearchEngine is truthy before calling document.querySelector(...) and before calling storedSearchEngine.replace(...); also null-check the resulting selectedRadioButton before setting .checked, and compute selector only when storedSearchEngine exists (or fall back to a safe default engine id); update references to storedSearchEngine, selectedRadioButton, activeSearchMode, and selector accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@scripts/search.js`:
- Around line 370-377: storedSearchEngine can be null when localStorage lacks
selectedSearchEngine-${activeSearchMode}, so guard its use before dereferencing:
check that storedSearchEngine is truthy before calling
document.querySelector(...) and before calling storedSearchEngine.replace(...);
also null-check the resulting selectedRadioButton before setting .checked, and
compute selector only when storedSearchEngine exists (or fall back to a safe
default engine id); update references to storedSearchEngine,
selectedRadioButton, activeSearchMode, and selector accordingly.
|
Well. Basically X is not a search engine. So I don't agree with it actually. |
It is on "Search On", not on "Search With", so it's fine.. |
📌 Description
Add X (formerly Twitter) as a new search engine option, allowing users to search directly on X from the new tab page.
Changes:
scripts/search.js: Addedengine10with URLhttps://x.com/search?q=index.html: Added X logo SVG icon (<symbol id="x-engine-icon">), dropdown item, and radio button option in settingsscripts/languages.js: RegisteredxEnginein bothtranslationMapandelementsMapxEngine: "X"translation key (brand name, kept as "X" across all languages)CHANGELOG.md: Updated underAddedsectionHow it works:
x.com/search?q={query}🎨 Visual Changes (Screenshots / Videos)
The X search engine appears with the official X logo icon in:
🔗 Related Issues
✅ Checklist
🤖 AI Assistance (Coding)
Overview
Adds X (formerly Twitter) as a new search engine option available in the search dropdown and settings panel. Users can select X and search queries redirect to
https://x.com/search?q={query}.Changes Made
Core Functionality
engine10entry tosearchQueryURLsmapping with X search URL (https://x.com/search?q=).charAt(...)extraction withreplace("engine", "")across selection/restore/switch flows (resolves engine10 parsing).UI & Markup
#x-engine-icon).Localization
xEnginein the translation mapping and addedxEngineDDelement mapping for dropdown text translation.xEngine: "X"translation entry to each locale's translations object (kept as "X" across languages).Documentation
Visuals & Testing
Search Behavior
https://x.com/search?q={query}.Notes