window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster already exists') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Create Google Chrome Extensions with Netflix subtitles styler - The Codest
The Codest
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Industries
    • Fintech & Banking
    • E-commerce
    • Adtech
    • Healthtech
    • Manufacturing
    • Logistics
    • Automotive
    • IOT
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
Back arrow GO BACK
2019-07-29
Software Development

Create Google Chrome Extensions with Netflix subtitles styler

Lukasz Kolko

Today we will create Google Chrome extensions for manipulating Netflix subtitle styles in real time. You will find information about creating extensions from scratch, some practical advice and general views on extension architecture. If you are not happy with the available Netflix subtitles options or just want to quickly create some extension to make life easier, this article is for you.

Our goals:

  • create extension logic
  • store settings in the browser Local Storage
  • autoload and activate extensions only on the Netflix page
  • create popup menu
  • create forms with subtitles options

Requirements:

  • basic knowledge of HTML, CSS and JavaScript

Netflix by its API sends every subtitle sentence separately. It uses CSS styles for styling subtitles. With access to the page DOM we can manipulate those received styles with Chrome extension.

The manifest

Firstly, we have to create the manifest file called manifest.json. This tells the browser about the extension setup, such as the UI files, background scripts and the capabilities the extension might have.

Here is a complete manifest.

 {
   "name": "Netflix subtitles styler",
   "version": "1.0",
   "description": "Netflix subtitles styler",
   "author": "twistezo",
   "permissions": ["tabs", "storage", "declarativeContent", "https://*.netflix.com/"],
   "background": {
     "scripts": ["background.js"],
     "persistent": false
   },
   "page_action": {
     "default_popup": "popup.html",
     "default_icon": "logo.png"
   },
   "manifest_version": 2
 }

As you see, we have some standard information, such as name, version, description, homepageurl and manifestversion.

One of the important parts of the manifest is the permissions section. This is an array with elements that our extension can access.

In our case, we need to have access to tabs to find the active tab, execute scripts and send messages between the UI and the extension. We need storage for store extension settings in the browser and declarativeContent for taking action depending on the tab content. The last element https://*.netflix.com/ allows extension access only to the netflix.com domain.

Chrome extensions have a separate logic from the UI so we need to have background.scripts, which tells the extension where it can find its logic. persistent: false means that this script will be used only if needed. page_action is the section with the UI part. We have here a simple HTML file for a popup menu and an extension’s PNG logo.

Extension logic

First we have to setup runtime.onInstalled behaviours, remove any current rules (for example from older versions) and declare function to add new rules. We use Local Storage for the storage settings so we can allocate default settings after the extension is installed.

We will be using three subtitle style parameters:

  • vPos – vertical position from bottom [px]
  • fSize – font size [px]
  • fColor – font color [HEX]

Create background.js:

chrome.runtime.onInstalled.addListener(() => {
chrome.storage.local.set({ vPos: 300, fSize: 24, fColor: "#FFFFFF" });

chrome.declarativeContent.onPageChanged.removeRules(undefined, () => {
chrome.declarativeContent.onPageChanged.addRules([
// array with rules
]);
});
});
```

Our rule goal is to disable the extension button on all domains other than netflix.com. We create new rule with PageStateMatcher conditions and declare ShowPageAction where new rule will be assigned.

 {
   conditions: [
     new chrome.declarativeContent.PageStateMatcher({
       pageUrl: { hostSuffix: "netflix.com" }
     })
   ],
   actions: [new chrome.declarativeContent.ShowPageAction()]
 }

The next step is to add tabs.onUpdated listener, which will execute our script while loading or refreshing the active tab.

 {
   conditions: [
     new chrome.declarativeContent.PageStateMatcher({
       pageUrl: { hostSuffix: "netflix.com" }
     })
   ],
   actions: [new chrome.declarativeContent.ShowPageAction()]
 }

Firstly we check that changeInfo.status has the status complete. This means that the website on this tab is loaded. Then we get settings from Local Storage and declare which script should be run on the current tab with tabId. Finally, in callback we send the message with settings from the UI to the script.

Extension UI

To create an extension popup menu with form, we create three files: popup.html and popup.css with visual layers and popup.js with logic for communicating between the menu and isolated background.js script.

Our UI goal:

Netflix styler

Here we have a simple HTML form with built-in validation: popup.html:

 <!DOCTYPE html>
 <html>
   <head>
     <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600" rel="stylesheet" />
     <link rel="stylesheet" href="popup.css" />
   </head>
   <body>
     <div class="container logo">
       NETFLIX SUBTITLES STYLER
     </div>
     <form id="popup-form" class="container">
       <div class="input-info">Vertical position from bottom [px]</div>
       <input class="form-control" id="vPos" type="number" value="" min="0" max="5000" />
       <div class="input-info">Font size [px]</div>
       <input id="fSize" type="number" value="" min="0" max="300" />
       <div class="input-info">Font color [HEX]</div>
       <input id="fColor" type="text" value="" pattern="^#[0-9A-F]{6}$" />
       <button id="change" type="submit">Change</button>
     </form>
     <div class="container footer">
       &copy; twistezo, 2019
     </div>
     <script src="popup.js"></script>
   </body>
 </html>

Styling the popup menu is not the goal of this article, so I suggest you visit https://github.com/twistezo/netflix-subtitles-styler and copy the whole popup.css file into your project.

UI logic – popup.js:

const form = document.getElementById("popup-form");
const inputElements = ["vPos", "fSize", "fColor"];

chrome.storage.local.get(inputElements, data => {
inputElements.forEach(el => {
document.getElementById(el).value = data[el];
});
});

form.addEventListener("submit", event => {
event.preventDefault();
const [vPos, fSize, fColor] = [...inputElements.map(el => event.target[el].value)];

chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
chrome.storage.local.set({ vPos, fSize, fColor });
chrome.tabs.executeScript(
tabs[0].id,
{
file: "script.js"
},
() => {
const error = chrome.runtime.lastError;
if (error) "Error. Tab ID: " + tab.id + ": " + JSON.stringify(error);

    chrome.tabs.sendMessage(tabs[0].id, { vPos, fSize, fColor });
  }
);

});
});
```

In above script, we load settings from Local Storage and attach them to form inputs. Then we create listener to submit event with functions for the save settings to Local Storage and send them by message to our script. As you see, we use Local Storage in every component. The Chrome extension doesn’t have its own data space so the simplest solution is to use browser local space like Local Storage. We also often use the sendMessage function. It’s caused by Chromme extensions’ architecture – they have separate logic from the UI.

The script

Now it is time to create script.js with logic for manipulating Netflix subtitles styles.

First, we create onMessage listener for receiving messages with settings from the extension.

 chrome.runtime.onMessage.addListener((message, _sender, _sendResponse) => {
   // function for manipulating styles
 });

Then in the same file we create the function for changing proper Netflix styles to our styles in real time.

changeSubtitlesStyle = (vPos, fSize, fColor) => {
console.log("%cnetflix-subtitles-styler : observer is working... ", "color: red;");

callback = () => {
// .player-timedText
const subtitles = document.querySelector(".player-timedtext");
if (subtitles) {
subtitles.style.bottom = vPos + "px";

  // .player-timedtext > .player-timedtext-container [0]
  const firstChildContainer = subtitles.firstChild;
  if (firstChildContainer) {
    // .player-timedtext > .player-timedtext-container [0] > div
    const firstChild = firstChildContainer.firstChild;
    if (firstChild) {
      firstChild.style.backgroundColor = "transparent";
    }

    // .player-timedtext > .player-timedtext-container [1]
    const secondChildContainer = firstChildContainer.nextSibling;
    if (secondChildContainer) {
      for (const span of secondChildContainer.childNodes) {
        // .player-timedtext > .player-timedtext-container [1] > span
        span.style.fontSize = fSize + "px";
        span.style.fontWeight = "normal";
        span.style.color = fColor;
      }
      secondChildContainer.style.left = "0";
      secondChildContainer.style.right = "0";
    }
  }
}

};

const observer = new MutationObserver(callback);
observer.observe(document.body, {
subtree: true,
attributes: false,
childList: true
});
};
```

For Netflix, every time it receives whole subtitle sentences it swaps only the subtitles part of the page DOM. So we have to use an observer function like MutationObserver, which will be triggering our changeSubtitlesStyle function every time when the page DOM has changed. In the callback function we see simple manipulation of styles. The commented lines have information about where you can find proper styles.

Time to run

I assume that you do not have a developer account in Chrome Webstore. So to run this extension go to chrome://extensions/ in your Chrome, click the Load unpacked, select folder with the extension and that’s it! Then, obviously go to the Netflix page for testing it.

Conclusions

As you see, it is easy to start creating some extensions that make life easier. The most important part is to understand Google Chrome Extension divided architecture and communication between components. This subtitles styler is only a simple demo of what you can do with the Chrome Extension API.

As you see, it is easy to start creating some extensions that make life easier. The most important part is to understand the Google Chrome Extension divided architecture and communication between components. This subtitles styler is only a simple demo of what you can do with the Chrome Extension API.

Imagine enhancing your viewing experience on platforms like Netflix with the power of extensions. For instance, the popular Netflix Party allows users to watch content together in sync. An extension icon in your toolbar can provide you quick access to control features when streaming Netflix. The idea behind tools like Netflix Extended is to add more functionality directly into the Netflix app through the Netflix extension integrated within Chrome. When browsing the Netflix website, such extensions can assist users in navigating through Netflix categories more efficiently or even discovering hidden Netflix content that they might not come across otherwise.

Furthermore, imagine being able to add a custom profile picture to your Netflix profile or having more control over the subtitles and playback speed. All of this can be accessible directly from the Chrome web browser, making the overall Netflix experience more tailored to each user’s preferences. Extensions not only enhance the functionalities of websites like Netflix but also elevate the overall user interaction, making it more immersive and user-friendly.

Useful links:

  • Repository with this project https://github.com/twistezo/netflix-subtitles-styler
  • Official Google guide https://developer.chrome.com/extensions/overview
  • Chrome Extension API https://developer.chrome.com/extensions/api_index

Related articles

Software Development

Build Future-Proof Web Apps: Insights from The Codest’s Expert Team

Discover how The Codest excels in creating scalable, interactive web applications with cutting-edge technologies, delivering seamless user experiences across all platforms. Learn how our expertise drives digital transformation and business...

THECODEST
Software Development

Top 10 Latvia-Based Software Development Companies

Learn about Latvia's top software development companies and their innovative solutions in our latest article. Discover how these tech leaders can help elevate your business.

thecodest
Enterprise & Scaleups Solutions

Java Software Development Essentials: A Guide to Outsourcing Successfully

Explore this essential guide on successfully outsourcing Java software development to enhance efficiency, access expertise, and drive project success with The Codest.

thecodest
Software Development

The Ultimate Guide to Outsourcing in Poland

The surge in outsourcing in Poland is driven by economic, educational, and technological advancements, fostering IT growth and a business-friendly climate.

TheCodest
Enterprise & Scaleups Solutions

The Complete Guide to IT Audit Tools and Techniques

IT audits ensure secure, efficient, and compliant systems. Learn more about their importance by reading the full article.

The Codest
Jakub Jakubowicz CTO & Co-Founder

Subscribe to our knowledge base and stay up to date on the expertise from the IT sector.

    About us

    The Codest – International software development company with tech hubs in Poland.

    United Kingdom - Headquarters

    • Office 303B, 182-184 High Street North E6 2JA
      London, England

    Poland - Local Tech Hubs

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warsaw, Poland

      The Codest

    • Home
    • About us
    • Services
    • Case Studies
    • Know How
    • Careers
    • Dictionary

      Services

    • It Advisory
    • Software Development
    • Backend Development
    • Frontend Development
    • Staff Augmentation
    • Backend Developers
    • Cloud Engineers
    • Data Engineers
    • Other
    • QA Engineers

      Resources

    • Facts and Myths about Cooperating with External Software Development Partner
    • From the USA to Europe: Why do American startups decide to relocate to Europe
    • Tech Offshore Development Hubs Comparison: Tech Offshore Europe (Poland), ASEAN (Philippines), Eurasia (Turkey)
    • What are the top CTOs and CIOs Challenges?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Copyright © 2025 by The Codest. All rights reserved.

    en_USEnglish
    de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek en_USEnglish