Web Reader

Instruction Manual

Understanding the Controls

Icon Control Description
Drag Handle Click and drag to move the toolbar anywhere on the screen
Play / Pause Start reading the page or pause the current reading
Stop Stop reading completely
Skip Back Go back to the previous sentence
Skip Forward Jump to the next sentence
Volume Open a volume slider, like on a video player, to make the voice louder or quieter
Settings Open the settings menu — see "The Settings Menu" below
Help Open this instruction manual
Minimize Shrink the toolbar to save screen space. Click the Web Reader button to expand it again.

The Settings Menu

Click the cogwheel button on the toolbar to open the settings menu:

Settings
Speed 100%
Dialect
Voice
  • SpeedDrag the slider to make the voice slower or faster
  • DialectChoose which Irish dialect to use (Connemara, Donegal, Kerry, or Waterford)
  • VoiceChoose a voice - (F) for female, (M) for male
  • Word definitions (Teanglann)When on, double-click any word to see its Teanglann definition
  • Announce links and imagesWhen on, the reader says "Link:" before links and "Image:" before image descriptions

Word definitions come from Teanglann.ie, developed and operated by Foras na Gaeilge. It hosts Ó Dónaill's Foclóir Gaeilge–Béarla, de Bhaldraithe's English–Irish Dictionary, An Foclóir Beag, and the grammar and pronunciation databases. Web Reader opens their entries directly and stores no dictionary content of its own.

Read a Full Page

1

Press the Play button

Click the green Play button on the control panel. The reader will start reading the page from the beginning.

2

Watch the text highlight

As the reader speaks, the current sentence will be highlighted in yellow so you can follow along.

Tá'n tionscnamh ABAIR lonnaithe sa Saotharlann Foghraíochta & Urlabhra i Scoil na nEolaíochtaí Teangeolaíochta, Urlabhra agus Cumarsáide i gColáiste na Tríonóide. Tá sé maoinithe ag An Roinn Forbartha Tuaithe agus Pobail agus Gaeltachta.

3

Pause or Stop

Click Pause to pause reading (click again to continue), or click Stop to stop completely.

Read Selected Text

1

Select text and click Read

Click and drag your mouse to highlight any text on the page. A small Read button will appear near your selection. Click it to hear the selected text read aloud.

Tá'n tionscnamh ABAIR lonnaithe sa Saotharlann Foghraíochta & Urlabhra i Scoil na nEolaíochtaí Teangeolaíochta, Urlabhra agus Cumarsáide i gColáiste na Tríonóide. Tá sé maoinithe ag An Roinn Forbartha Tuaithe agus Pobail agus Gaeltachta.Read

Keyboard Shortcuts

Note: Some shortcuts are managed by Chrome. Visit chrome://extensions/shortcuts to customize global shortcuts.

Play / Pause Alt + P
Stop Alt + S
Read Selection Alt + R
Full Page Read Alt + F
Next Sentence Alt + →
Previous Sentence Alt + ←
Next Paragraph Alt + ↓
Previous Paragraph Alt + ↑
Speed Up Alt + ]
Slow Down Alt + [
Toggle Panel Alt + W

Frequently Asked Questions

Q: I don't see the control panel
A: Make sure the extension is turned on. Click the Web Reader icon in your browser toolbar — the round power button at the top of the menu glows green when the extension is on.
Q: I don't hear any sound
A: Check that your computer's volume is turned up. Also make sure you're connected to the internet - the reader needs an internet connection to work.
Q: The voice sounds wrong
A: Try changing the dialect or voice in the settings menu (the cogwheel icon on the toolbar). Different dialects sound quite different!
Q: The toolbar is blocking content on the page
A: You can move the toolbar by dragging the dotted handle on the left side. You can also click the minimize button to shrink it - click the speaker icon to expand it again.
Q: How do I turn off the extension completely?
A: Click the Web Reader icon in your browser toolbar to open the menu, then click the round power button at the top. It stops glowing green, and the toolbar will disappear until you switch it back on.

Installation Instructions

1

Copy the script tag

<script src="https://webreader.abair.ie/v1/script.js" async></script>

This is the 1.x channel: it picks up fixes and compatible improvements automatically but never a breaking change. If you need a build that is frozen byte-for-byte, or you use Subresource Integrity, pin an exact version instead — see Versions and pinning below.

2

Insert it before the closing </body> tag

<body>
  <!-- page content -->

  <script src="https://webreader.abair.ie/v1/script.js" async></script>
</body>
3

Allow the widget in your Content Security Policy

Skip this if your site sends no Content-Security-Policy header. If it does, the widget is blocked until you allow its origins — this is the most common reason a correct installation appears to do nothing at all. See Content Security Policy below for the directives and a copy-pasteable snippet.

Versions and pinning

Three script URLs are published. They all serve the same widget; they differ in when it changes underneath you. Pick one deliberately — it is the difference between a fix arriving automatically and a build that is guaranteed byte-for-byte stable.

Script URL When it changes Cached for Choose this if
https://webreader.abair.ie/v1/script.js Automatically, on every release in the 1.x line — fixes and backwards-compatible additions, never a breaking change. Minutes Recommended. You want improvements and security fixes without doing anything, but you never want an upgrade that could break your page.
https://webreader.abair.ie/v1.3.0/script.js Never. That exact build, permanently. Nothing about it can change after you have tested it. One year (immutable) You need a reproducible deployment, you are subject to change control or a security review, or you want to use Subresource Integrity.
https://webreader.abair.ie/script.js Automatically, on every release — including a future major version that may change defaults or configuration. Minutes You installed the widget before versioned URLs existed. This URL stays supported and always serves the newest build; moving to /v1/script.js is a one-line change and is safer.

Current version: 1.3.0. The pinned URL for it is https://webreader.abair.ie/v1.3.0/script.js. Every released version stays available at its own address permanently, so the pinned URL you install today keeps working. To check which build a page actually loaded, read window.WebReader.version in the browser console.

What the numbers mean

  • Major (1.x.x2.x.x) — a change that can require you to act: a configuration key removed or renamed, a default reversed, a behaviour change you would notice. Announced before release. A /v1/ URL will not follow the widget to 2.x.
  • Minor (1.1.x1.2.x) — new capability, existing pages keep working unchanged.
  • Patch (1.1.01.1.1) — a fix. No configuration change.

Pinning is permanent, and safe. Each released version is stored as its own file and is never rewritten, so /v1.3.0/script.js will serve the same bytes indefinitely — an integrity hash taken against it cannot stop matching. The trade-off is the obvious one: a pinned URL never receives fixes, including security fixes, so review it periodically and update deliberately. If you would rather receive 1.x releases automatically, use /v1/script.js.

Subresource Integrity

The script is served with permissive CORS headers, so you can verify it with Subresource Integrity. Use SRI only with a pinned /v1.3.0/ URL — the rolling URLs change content by design, and the hash would stop matching on the next release, blocking the script entirely.

<script src="https://webreader.abair.ie/v1.3.0/script.js"
        integrity="sha384-PASTE_THE_HASH_YOU_COMPUTED"
        crossorigin="anonymous" async></script>

Compute the hash yourself from the exact URL you are pinning — do not copy one from documentation:

curl -s https://webreader.abair.ie/v1.3.0/script.js \
  | openssl dgst -sha384 -binary \
  | openssl base64 -A

The crossorigin="anonymous" attribute is required whenever integrity is present; without it the browser refuses the cross-origin script. No credentials or cookies are sent.

Configuration

Optional. Define window.WebReaderConfig before the script tag to override defaults.

<script>
  window.WebReaderConfig = {
    locale: 'ga',
    panelPosition: 'bottom-right',
    collapseByDefault: true,
    speed: 1.0,
    dialect: 'ga_CO',
    voice: 'ga_CO_snc_piper',
    wordLookup: false,
    announceMedia: false,
    disableTeanglann: true,
    keyboardShortcuts: false,
    nonce: undefined
  };
</script>
<script src="https://webreader.abair.ie/v1/script.js" async></script>

The reading defaults below (speed, dialect, voice, wordLookup, announceMedia) seed a visitor's settings on their first visit only. After a visitor changes a setting in the panel, their own choice is stored and takes over. disableTeanglann, keyboardShortcuts and nonce are not visitor preferences: they apply on every load.

Bad configuration never breaks your page. Every value is validated as it is read. An unknown key, a wrong type, or an out-of-range number is ignored, the documented default is used instead, and a single explanatory warning is written to the browser console prefixed with [WebReader]. The widget does not throw into your code.

Two defaults differ from the installed browser extension. In the embedded widget the Teanglann dictionary lookup is locked off (disableTeanglann defaults to true) and auto-scroll starts off. Lookup is locked so that nothing on your site can contact teanglann.ie, and visitors get no toggle for it; auto-scroll is off so the widget never moves your page under a visitor's cursor. Set disableTeanglann: false to offer lookup — add wordLookup: true to have it on from the first visit — and visitors can turn auto-scroll on themselves in the panel.

locale
Interface language. Accepts 'ga' (Irish) or 'en' (English). Defaults to 'ga'.
panelPosition
Initial panel coordinates as { top, left } in pixels. Falls back to the bottom-right corner.
collapseByDefault
Initial panel state on first visit. true (default) starts collapsed; false starts expanded. Once a visitor toggles the panel, their choice is stored in localStorage and overrides this setting.
speed
Default playback speed multiplier from 0.5 (slowest) to 1.5 (fastest); 1.0 is normal. First-visit default.
dialect
Default dialect. One of 'ga_CO' (Connemara), 'ga_UL' (Donegal), 'ga_MU' (Kerry), 'ga_MU_ar' (Waterford). Picks that dialect's default voice unless voice is also set. First-visit default.
voice
Default voice id, e.g. 'ga_CO_snc_piper' (Sibéal), 'ga_UL_anb_piper' (Áine), 'ga_MU_nnc_piper' (Neasa). Sets the matching dialect automatically. First-visit default.
wordLookup
Whether double-click Teanglann dictionary lookup starts enabled. true or false (default), so no request reaches teanglann.ie unless a visitor opts in. Has no effect on its own in the embedded widget: disableTeanglann removes the feature unless you set it to false. First-visit default; visitors can still toggle it.
announceMedia
Whether spoken "Link:" and "Image:" announcements start enabled. true or false (default). First-visit default.
disableTeanglann
Hard lock. When true, the Teanglann lookup feature is removed entirely — no double-click lookup, no Alt+L, and the toggle is hidden from the panel. Applied on every load, overriding wordLookup. Defaults to true in the embedded widget: set it to false to offer lookup to your visitors.
keyboardShortcuts
Whether the widget binds its Alt keyboard shortcuts on your pages. Defaults to false in the embedded widget. They are off because the shortcut set claimed Alt+ and Alt+, which browsers use for Back and Forward — a widget on someone else's site should not take those. Set true only if you have checked the bindings do not collide with your own.
nonce
A CSP nonce string. Only needed as a fallback on browsers that cannot use constructable stylesheets; the widget then stamps this nonce on the one <style> element it must create, so a strict style-src policy still accepts it. It must be the same nonce your server put in that response's Content-Security-Policy header, and a nonce must be freshly generated per response. See Content Security Policy below.

JavaScript API

Once the script has loaded it exposes window.WebReader. Use it to drive playback from your own controls, react to reading events, or remove the widget again. Nothing else on the object is part of the supported interface.

Member What it does
version The version string of the loaded build, e.g. '1.3.0'. Useful in bug reports and to confirm a pinned URL is serving what you expect.
play() Starts reading, or resumes after a pause. Equivalent to pressing play in the panel.
pause() Pauses playback, keeping the position so play() continues from there.
stop() Stops reading and clears the highlight and the position.
configure(partial) Applies configuration after load. Takes the same keys as window.WebReaderConfig and only the ones you pass. Values are validated the same way; invalid ones are ignored with a console warning.
destroy() Stops playback and removes the panel, its listeners and its DOM. Call this before your single-page app tears down the view that hosted it, so nothing is left behind.
on(event, handler)
off(event, handler)
Subscribe and unsubscribe. Events: 'play', 'stop', 'complete' (reached the end of the content) and 'error' (synthesis failed or the network is unavailable). Pass the same function reference to off that you passed to on.

Because the tag is async, window.WebReader does not exist yet when your own inline scripts run. Wait for the script element's load event:

const script = document.createElement('script');
script.src = 'https://webreader.abair.ie/v1/script.js';
script.async = true;

script.addEventListener('load', () => {
  const wr = window.WebReader;
  console.log('Web Reader', wr.version);

  // React to reading state.
  wr.on('play',     () => document.body.classList.add('is-reading'));
  wr.on('stop',     () => document.body.classList.remove('is-reading'));
  wr.on('complete', () => document.body.classList.remove('is-reading'));
  wr.on('error',    (err) => console.warn('Web Reader error', err));

  // Drive it from your own button.
  document.querySelector('#read-aloud')
    ?.addEventListener('click', () => wr.play());

  // Change settings at runtime.
  wr.configure({ speed: 0.9, voice: 'ga_UL_anb_piper' });
});

document.body.appendChild(script);

Single-page apps: load the script once, not per route. If you must unmount it, call window.WebReader.destroy() in your cleanup function — see the React example below.

Content Security Policy

If your site sends a Content-Security-Policy header, the widget will be blocked until you allow the origins it uses. This is the single most common reason an installation appears to do nothing. Add these directives to your existing policy — do not replace your policy with this snippet.

Content-Security-Policy:
  script-src  'self' https://webreader.abair.ie;
  connect-src 'self' https://synthesis.abair.ie;
  frame-src   https://www.teanglann.ie;
  img-src     'self' data:;
Directive Add Why Required
script-src https://webreader.abair.ie Loads the widget bundle itself. Always
connect-src https://synthesis.abair.ie The fetch() that requests synthesised audio. Without it nothing is spoken and the console shows a CSP violation on every play. Always
frame-src https://www.teanglann.ie The dictionary lookup panel, which is an iframe onto Teanglann. Only if you have set disableTeanglann: false, so lookup can be used. Not needed on the default configuration. Note that frame-src falls back to child-src, then default-src.
img-src data: The dropdown chevrons in the panel's <select> controls are inline SVGs delivered as data: URIs. Without this the selects render without their arrow. Always
style-src Usually nothing The panel's CSS is applied as a constructable stylesheet adopted into the widget's shadow root, which is not governed by style-src. The widget therefore does not require 'unsafe-inline'. See the note below for older browsers.
media-src Nothing Audio is decoded and played through the Web Audio API, not an <audio> element, so no media is loaded by URL. Never

Older browsers and style-src. Where constructable stylesheets are unavailable, the widget falls back to creating a single <style> element, which a strict policy would block. You have two options, in order of preference: pass a nonce in window.WebReaderConfig matching the nonce in that response's own style-src (generate a fresh, unpredictable nonce per response — a fixed one is no protection at all), or, if you cannot use nonces, add 'unsafe-inline' to style-src. Current browsers need neither.

If your policy uses default-src without the directives above, every one of them falls back to default-src and the widget is blocked. Name them explicitly. To find what a browser is actually refusing, open the console: CSP violations are reported there naming the exact directive, and you can test a change safely by first sending it as Content-Security-Policy-Report-Only.

Using Subresource Integrity as well? Add crossorigin="anonymous" to the script tag alongside integrity, and pin a /v1.3.0/ URL — see Versions and pinning above.

React / Next.js Integration

The script must run in the browser. In React or Next.js, inject it from a client-side useEffect.

1

Add WebReader.tsx

"use client";

import { useEffect } from "react";

export default function WebReader() {
  useEffect(() => {
    if (document.getElementById("webreader-embed-script")) return;

    (window as any).WebReaderConfig = {
      locale: "ga",
      panelPosition: 'bottom-right',
    };

    const script = document.createElement("script");
    script.id = "webreader-embed-script";
    script.src = "https://webreader.abair.ie/v1/script.js";
    script.async = true;
    document.body.appendChild(script);

    // Strict Mode mounts effects twice in development; destroy() makes the
    // teardown safe and leaves no orphaned panel behind.
    return () => {
      (window as any).WebReader?.destroy?.();
      script.remove();
    };
  }, []);

  return null;
}
2

Mount it in the root layout

import WebReader from "./WebReader";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <WebReader />
      </body>
    </html>
  );
}

Troubleshooting

Q: The panel does not appear after installation.
A: Confirm the tag is inside <body> rather than <head>, the file is saved, and the browser cache is cleared. Use a hard refresh: Ctrl+Shift+R on Windows/Linux, Cmd+Shift+R on macOS. If it still does not appear, open the browser console: a message about "Refused to load the script" means your Content Security Policy is blocking it.
Q: The console says "Refused to connect" or "Refused to load", and nothing is spoken.
A: That is a Content Security Policy violation, and the message names the directive at fault. script-src blocks the widget from loading at all; connect-src lets the panel appear but blocks the synthesis request, so nothing is spoken. See Content Security Policy above for the exact directives.
Q: The script URL returns 404.
A: That version was never released. Released versions are kept permanently, so a 404 means the number in your URL is wrong rather than retired — check it for a typo against the current version above. Note that only full x.y.z numbers are pinnable: /v1.3/script.js is not an address. Use /v1/script.js for the rolling 1.x channel, or a complete version for an exact pin.
Q: The keyboard shortcuts do not work.
A: They are switched off by default in the embedded widget, because the old bindings took over the browser's own Alt+ / Alt+ Back and Forward keys on your visitors' pages. Set keyboardShortcuts: true to enable them once you have confirmed they do not collide with your site's own bindings.
Q: The panel starts collapsed.
A: This is the default. Expanding the panel persists the choice to localStorage for subsequent visits.
Q: Are non-Irish voices available?
A: Not yet. Every synthesised voice is Irish today, and the interface alone can be switched to English with locale: 'en'. Bilingual voices are in active development. Code-switching comes first, so an Irish voice handles English words and phrases inside Irish text, with Hiberno-English versions of our voices to follow.
Q: Is there a usage fee?
A: No. The service is provided free of charge by the ABAIR research project. You do not have to add anything: the collapsed panel button already carries the ABAIR mark, and that is attribution enough. If you would also like to credit us in your own words, a line in your footer or accessibility statement such as “Irish text-to-speech by ABAIR, Trinity College Dublin”, linked to abair.ie, is very welcome.
Q: Where do I report issues?
A: Contact the ABAIR team through the form at abair.ie.