Skip to content

Plugins

The Plugins sidebar group is the bridge between the Enjoy web app and other Enjoy surfaces — most notably the browser extension. Use it whenever you want to learn outside the web app, or when you want to bring content from a streaming site into your library.

Where to Find It

Open the web app sidebar and scroll down to the Plugins group near the bottom. It sits between the main feature group and the secondary entries (Settings, Account, Logout).

The current entries are:

PluginWhat it does
Chrome ExtensionOpens the Chrome Web Store listing for the Enjoy browser extension in a new tab.

Chrome Extension

The Chrome extension brings Enjoy's learning features to YouTube, Netflix, and other supported sites. After installing it, you can:

  • Open the sidepanel to read transcripts, vocabulary, and notes without leaving the page
  • Use Echo Mode to shadow a YouTube line and get instant pronunciation feedback
  • Use Dictation Mode to type what you hear and improve listening accuracy
  • Save media to your Enjoy library so it syncs to the web app and other devices

Shared Account and Sync

The extension uses the same Enjoy account as the web app. Vocabulary, recordings, and notes you create in the extension sync through the Sync feature and appear in the web app's Vocabulary and library views.

Installation

For a step-by-step walkthrough, see the extension's Installation guide.

Adding a New Plugin

To register a new entry in the Plugins group, add an item to the navPlugins array in apps/web/src/components/layout/app-sidebar.tsx:

tsx
const navPlugins = [
  {
    title: t("plugins.chromeExtension", { ns: "common" }),
    url: "https://chromewebstore.google.com/detail/enjoy-echo/...",
    icon: IconBrandChrome,
    target: "_blank",
  },
  // Add new plugin entries here
]

Each entry needs:

FieldPurpose
titleLocalized label via t(...) with a defaultValue fallback
urlExternal link or in-app route
iconTabler icon component (or another icon from the project's icon set)
target"_blank" for external links, omit for in-app routes

The group label itself is sourced from the common namespace:

tsx
<SidebarGroupLabel>{t("plugins.title", { ns: "common", defaultValue: "Plugins" })}</SidebarGroupLabel>

⚠️ Nested-key gotcha: When a key resolves to a JSON object in the translation file, calling t("plugins") (without specifying a child key) returns the object rather than a string. i18next then renders an error string in production. Always specify a leaf key (t("plugins.title")) and provide a defaultValue so the sidebar still renders if the namespace is missing.