{"id":387238,"date":"2026-10-20T18:50:51","date_gmt":"2026-10-20T18:50:51","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/simple-browser-tts\/"},"modified":"2026-10-20T18:50:41","modified_gmt":"2026-10-20T18:50:41","slug":"ogs-simple-browser-text-to-speech","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/ogs-simple-browser-text-to-speech\/","author":23579489,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.15","stable_tag":"1.0.15","tested":"7.1.3","requires":"6.3","requires_php":"7.4","requires_plugins":null,"header_name":"OGS Simple Browser Text to Speech","header_author":"Open Growth Solutions","header_description":"Adds free browser-based text-to-speech to selected WordPress post types using the Web Speech API.","assets_banners_color":"","last_updated":"2026-10-20 18:50:41","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":43,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.15":{"tag":"1.0.15","author":"jaimepaezv","date":"2026-10-20 18:50:41","revision":3757307}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.15"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[1953,61815,16722,1449,287781],"plugin_category":[34],"plugin_contributors":[286303],"plugin_business_model":[],"class_list":["post-387238","plugin","type-plugin","status-publish","hentry","plugin_tags-accessibility","plugin_tags-speech-synthesis","plugin_tags-text-to-speech","plugin_tags-tts","plugin_tags-web-speech","plugin_category-accessibility","plugin_contributors-jaimepaezv","plugin_committers-jaimepaezv"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/ogs-simple-browser-text-to-speech.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>OGS Simple Browser Text to Speech adds a lightweight Listen \/ Pause \/ Resume \/ Stop player to selected public post types.<\/p>\n\n<p>Key characteristics:<\/p>\n\n<ul>\n<li>No API key or plugin-managed TTS service. Speech is provided by the visitor's browser\/operating system; some installed voices may use the browser vendor's remote speech service.<\/li>\n<li>No audio generation or server-side processing.<\/li>\n<li>Enabled by post type, so all existing and future posts of enabled types are covered automatically.<\/li>\n<li>Reads the final rendered DOM instead of modifying stored post content.<\/li>\n<li>Automatic content detection with manual overrides using <code>.simple-browser-tts-content<\/code> and <code>.simple-browser-tts-ignore<\/code>.<\/li>\n<li>Visitor-selectable reading speed, stored locally in the browser only when visitor speed controls are enabled.<\/li>\n<li>Progressive enhancement: if SpeechSynthesis is unavailable, the site content remains unaffected.<\/li>\n<\/ul>\n\n<p>Default content type: Posts.<\/p>\n\n<h3>Page builder compatibility<\/h3>\n\n<p>The plugin is builder-agnostic: it reads the final rendered frontend DOM and does not depend on private builder PHP APIs. It recognizes standard WordPress semantic markup plus selected stable roots for Elementor, Beaver Builder, and Bricks, then falls back to <code>article<\/code> or <code>main<\/code>.<\/p>\n\n<p>This approach is intended to work with content rendered by Gutenberg, Classic Editor, LiveCanvas and other popular builders, but builders and themes can produce arbitrary markup. For exact control on any builder or custom theme:<\/p>\n\n<ul>\n<li>Add class <code>simple-browser-tts-content<\/code> to the container that should be read.<\/li>\n<li>Add class <code>simple-browser-tts-ignore<\/code> to content that should not be read.<\/li>\n<li>Or configure a CSS content selector under Settings &gt; Text to Speech &gt; Advanced.<\/li>\n<\/ul>\n\n<p>LiveCanvas normally places page content in a single <code>&lt;main&gt;<\/code> element, which is covered by the fallback detector. Other builders that render content inside <code>article<\/code> or <code>main<\/code> are handled the same way.<\/p>\n\n<h3>Browser notes<\/h3>\n\n<p>Speech quality, available voices and pause\/resume behavior are provided by the browser and operating system. The plugin prefers a local voice matching the page language when one is available and otherwise uses only a voice matching that language. If no matching voice is exposed, it leaves voice selection to the browser instead of forcing a voice from another language. Because the Web Speech API uses a document-wide speech queue, the plugin will not start while another script is already using speech synthesis on the page. Background or locked-screen speech can still be limited by the browser or mobile operating system.<\/p>\n\n<h3>Privacy<\/h3>\n\n<p>OGS Simple Browser Text to Speech does not send content, analytics, telemetry or settings to the plugin author and does not make its own network requests for speech synthesis.<\/p>\n\n<p>Speech synthesis itself is a browser\/operating-system feature. The plugin neither selects nor communicates with a third-party speech provider. Depending on the visitor's browser, operating system and selected voice, the user agent may implement a voice locally or through a remote service operated by its vendor. Site owners should account for that browser\/OS behavior in their own privacy disclosures when applicable.<\/p>\n\n<p>When visitor speed controls are enabled, the selected reading speed is stored in the visitor's browser using <code>localStorage<\/code>. The plugin also stores a small first-use marker after the visitor first interacts with the player. It uses <code>localStorage<\/code> when available and falls back to <code>sessionStorage<\/code> if persistent storage is blocked. No cookie is created by the plugin and these values are not transmitted by the plugin.<\/p>\n\n<h3>Keyboard shortcuts<\/h3>\n\n<p>OGS Simple Browser Text to Speech does not currently register global keyboard shortcuts. If shortcuts are introduced in a future release, they will be documented in this section together with their scope and accessibility behavior.<\/p>\n\n<h3>Developer notes<\/h3>\n\n<p>Use the <code>simple_browser_tts_should_load<\/code> filter to override whether TTS assets load on a specific frontend request. The default behavior remains unchanged: enabled singular post types only.<\/p>\n\n<p>Developers can also set an explicit mount target without changing plugin templates:<\/p>\n\n<ul>\n<li><code>simple_browser_tts_player_mount_selector<\/code> returns a CSS selector for the element used as the mount target. Return an empty string to keep automatic placement.<\/li>\n<li><code>simple_browser_tts_player_mount_position<\/code> controls insertion relative to that target and accepts <code>beforebegin<\/code>, <code>afterbegin<\/code>, <code>beforeend<\/code>, or <code>afterend<\/code>.<\/li>\n<\/ul>\n\n<p>If the custom selector is missing or invalid on the current page, the plugin falls back to its normal before\/after placement around the detected content root.<\/p>\n\n<p>The frontend player is fully scoped under <code>.simple-browser-tts-player<\/code> and exposes CSS custom properties for theme integration. Common overrides include <code>--simple-browser-tts-bg<\/code>, <code>--simple-browser-tts-border<\/code>, <code>--simple-browser-tts-text<\/code>, <code>--simple-browser-tts-accent<\/code>, <code>--simple-browser-tts-accent-text<\/code>, <code>--simple-browser-tts-error<\/code>, <code>--simple-browser-tts-radius<\/code>, and <code>--simple-browser-tts-btn-radius<\/code>. The default <code>--simple-browser-tts-accent-text<\/code> uses the system <code>Canvas<\/code> color; themes that override <code>--simple-browser-tts-accent<\/code> should also override <code>--simple-browser-tts-accent-text<\/code> when needed to preserve sufficient contrast. The player also exposes <code>is-playing<\/code> and <code>is-paused<\/code> state classes for optional state-specific styling.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code> or install the ZIP from Plugins &gt; Add New &gt; Upload Plugin.<\/li>\n<li>Activate OGS Simple Browser Text to Speech.<\/li>\n<li>Go to Settings &gt; Text to Speech.<\/li>\n<li>Posts are enabled by default. Select any additional public post types as needed.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20the%20plugin%20send%20post%20content%20to%20an%20external%20api%3F\"><h3>Does the plugin send post content to an external API?<\/h3><\/dt>\n<dd><p>The plugin does not call an external TTS API. It passes text to the browser's Web Speech API. Some browsers or operating systems may implement particular voices using their own remote services; that communication, when it occurs, is performed by the user agent rather than by the plugin.<\/p><\/dd>\n<dt id=\"how%20do%20i%20choose%20exactly%20what%20is%20read%3F\"><h3>How do I choose exactly what is read?<\/h3><\/dt>\n<dd><p>Add <code>simple-browser-tts-content<\/code> to the container to read, add <code>simple-browser-tts-ignore<\/code> to content to skip, or set CSS selectors under Settings &gt; Text to Speech &gt; Advanced.<\/p><\/dd>\n<dt id=\"why%20is%20no%20player%20shown%20on%20a%20page%3F\"><h3>Why is no player shown on a page?<\/h3><\/dt>\n<dd><p>The plugin loads only on enabled singular post types and only when it can find enough readable content. JavaScript must be enabled and the browser must expose the Web Speech API.<\/p><\/dd>\n<dt id=\"why%20do%20voices%20differ%20between%20devices%3F\"><h3>Why do voices differ between devices?<\/h3><\/dt>\n<dd><p>Voice availability is controlled by the visitor's browser and operating system. The plugin does not bundle speech engines or voices.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.15<\/h4>\n\n<ul>\n<li>Harden settings sanitization for malformed post type and reading-speed inputs.<\/li>\n<li>Keep the OGS text domain aligned with the reserved slug and release directory.<\/li>\n<\/ul>\n\n<h4>1.0.14<\/h4>\n\n<ul>\n<li>Updated plugin name, author, slug, text domain, and translation template.<\/li>\n<\/ul>\n\n<h4>1.0.13<\/h4>\n\n<ul>\n<li>Use a full plugin-specific namespace for PHP symbols, hooks, settings, JavaScript globals, DOM hooks and CSS variables.<\/li>\n<li>Guarantee speech chunks stay within the configured maximum, including CJK text, long URLs and other text without spaces.<\/li>\n<li>Harden player mounting so valid but unsuitable selectors cannot abort frontend initialization.<\/li>\n<li>Avoid starting while another script is already using the document-wide SpeechSynthesis queue and make startup watchdogs rely on this plugin's utterance events.<\/li>\n<li>Make first-use help match the enabled controls and persist it only after the visitor interacts with the player.<\/li>\n<li>Replace repeated polling for late content with a throttled, bounded MutationObserver.<\/li>\n<li>Improve settings preview semantics and language-tag wording.<\/li>\n<li>Clarify browser\/OS remote-voice behavior and move older release history to changelog.txt.<\/li>\n<\/ul>\n\n<h4>1.0.12<\/h4>\n\n<ul>\n<li>Add a customizable error design token and document accent-text contrast customization.<\/li>\n<\/ul>\n\n<h4>1.0.11<\/h4>\n\n<ul>\n<li>Improve content-type selection, add settings-page player preview, and document keyboard-shortcut policy.<\/li>\n<\/ul>","raw_excerpt":"Free browser-based text to speech for WordPress using the Web Speech API.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/387238","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=387238"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/jaimepaezv"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=387238"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=387238"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=387238"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=387238"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=387238"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=387238"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}