Custom DOM Rules
Configure custom DOM rules to control translation behavior on specific websites
Overview
Read Frog allows you to define custom DOM rules to control how elements are translated on specific websites. These rules are defined in dom-rules.ts and support two main behaviors:
- Force elements not to be translated - Skip translation for specific elements
- Force block translation - Make inline elements translate as block elements (with line breaks)
Configuration File Location
The custom rules are defined in the extension repository:
src/utils/constants/dom-rules.tsAvailable Rule Types
1. Custom Don't Walk Into Element Selectors
Use CUSTOM_DONT_WALK_INTO_ELEMENT_SELECTOR_MAP to prevent translation of specific elements on certain domains.
Syntax:
export const CUSTOM_DONT_WALK_INTO_ELEMENT_SELECTOR_MAP: Record<string, string[]> = {
'example.com': [
'.selector-1',
'#element-id',
'custom-element > *',
],
}Example:
export const CUSTOM_DONT_WALK_INTO_ELEMENT_SELECTOR_MAP: Record<string, string[]> = {
'chatgpt.com': [
'.ProseMirror',
],
'arxiv.org': [
'.ltx_listing',
],
'www.reddit.com': [
'faceplate-screen-reader-content > *',
'reddit-header-large *',
'shreddit-comment-action-row > *',
],
'www.youtube.com': [
'#masthead-container *',
'#guide-inner-content *',
'#metadata *',
'#channel-name',
'.translate-button',
'.yt-lockup-metadata-view-model__metadata',
'.yt-spec-avatar-shape__badge-text',
'.shortsLockupViewModelHostOutsideMetadataSubhead',
'ytd-comments-header-renderer',
'#top-row',
'#header-author',
'#reply-button-end',
'#more-replies',
'#info',
'#badges *',
],
}Use Cases:
- Skip navigation menus and headers
- Exclude interactive UI elements
- Prevent translation of code editors or technical content
- Avoid translating metadata sections
2. Custom Force Block Translation Selectors
Use CUSTOM_FORCE_BLOCK_TRANSLATION_SELECTOR_MAP to force inline elements to be translated as block elements (with line breaks).
Syntax:
export const CUSTOM_FORCE_BLOCK_TRANSLATION_SELECTOR_MAP: Record<string, string[]> = {
'example.com': [
'.force-block-selector',
],
}Example:
export const CUSTOM_FORCE_BLOCK_TRANSLATION_SELECTOR_MAP: Record<string, string[]> = {
'github.com': [
'.react-directory-row-commit-cell *',
],
}Use Cases:
- Force commit messages to appear on separate lines
- Ensure list items are translated individually
- Improve readability by breaking up dense inline content
How to Add Custom Rules
Step 1: Identify the Website Domain
Use the exact domain as it appears in the browser's address bar:
- Use
'example.com'forhttps://example.com - Use
'www.example.com'forhttps://www.example.com
Step 2: Find Element Selectors
Use browser DevTools to find CSS selectors:
- Open the website
- Right-click the element you want to target
- Select "Inspect" or "Inspect Element"
- Right-click the HTML element in DevTools
- Copy the selector (CSS Selector or create your own)
Step 3: Add Rules to Configuration
Open dom-rules.ts and add your rules:
export const CUSTOM_DONT_WALK_INTO_ELEMENT_SELECTOR_MAP: Record<string, string[]> = {
// ... existing rules ...
'your-website.com': [
'.header-navigation',
'#sidebar-menu',
'.code-block',
],
}Step 4: Test Your Rules
-
Run the development server:
pnpm dev -
Navigate to the website
-
Verify that the elements are handled correctly
-
Adjust selectors as needed
Best Practices
Selector Specificity
- Be specific enough to target only the intended elements
- Avoid overly broad selectors like
*ordivalone - Use class names, IDs, or element combinations
Performance Considerations
- Keep the number of selectors reasonable
- Test on actual pages to ensure performance is acceptable
- Avoid complex descendant selectors when simpler ones work
Maintainability
- Group related selectors together
- Add comments explaining why rules are needed
- Use meaningful selector names when possible
Common Patterns
Excluding Navigation Elements
'example.com': [
'nav *',
'header *',
'.navigation',
]Excluding Interactive UI
'example.com': [
'button',
'input',
'select',
'.modal',
'.dropdown',
]Excluding Technical Content
'example.com': [
'pre',
'code',
'.code-block',
'.terminal',
]Global DOM Rules
In addition to custom rules, Read Frog has several global rules that apply to all websites:
Force Block Tags
Elements that are always treated as block-level:
export const FORCE_BLOCK_TAGS = new Set([
'BODY',
'H1',
'H2',
'H3',
'H4',
'H5',
'H6',
'BR',
'FORM',
'SELECT',
'BUTTON',
'LABEL',
'UL',
'OL',
'LI',
'BLOCKQUOTE',
'PRE',
'ARTICLE',
'SECTION',
'FIGURE',
'FIGCAPTION',
'HEADER',
'FOOTER',
'MAIN',
'NAV',
])Don't Walk and Translate Tags
Elements that are never traversed for translation:
export const DONT_WALK_AND_TRANSLATE_TAGS = new Set([
'HEAD',
'TITLE',
'HR',
'INPUT',
'TEXTAREA',
'IMG',
'VIDEO',
'AUDIO',
'CANVAS',
'SOURCE',
'TRACK',
'META',
'SCRIPT',
'NOSCRIPT',
'STYLE',
'LINK',
'PRE',
'svg',
...MATH_TAGS,
])Troubleshooting
Rules Not Working
- Check domain spelling - Ensure the domain matches exactly
- Verify selector syntax - Test selectors in browser DevTools console
- Clear cache - Reload the extension and refresh the page
- Check selector specificity - Element might be matched by a more specific rule
Elements Still Being Translated
- Check if the element is a child of an excluded element
- Verify the selector targets the correct elements
- Look for dynamic elements loaded after page load
Translation Breaking Page Layout
- Use force block rules sparingly
- Test on multiple pages of the same website
- Consider using
!translaterules instead of force block
Contributing Custom Rules
If you've created rules that benefit others, consider contributing them:
- Test thoroughly on multiple pages
- Document why the rules are needed
- Submit a Pull Request with your changes
- Follow the Contribution Guidelines
See the Code Contribution Guide for more details on submitting changes.
Contribution Guide
Let's build a better language learning product together
DOM Node Interface Hierarchy
The following content will provide a detailed introduction to the inheritance relationships between the three interfaces `Node`, `Element`, and `HTMLElement` in the DOM, as well as their respective main subtypes.