40

I have a Chrome extension content script that I want to run on Trello boards. For now, it contains only:

console.log("Hello, world!");

When you open the Trello board page through an internal link, like from the My Boards page, the content script does not run. It does run after you refresh the page though.

My manifest file contains:

{
  "manifest_version": 2,

  "name": "Temp Ext",
  "version": "1.0",

  "content_scripts": [
    {
      "matches": ["*://trello.com/b/*"],
      "js":["contentscript.js"]
    }
  ]
}

Can anyone help me figure out why the script doesn't run at the time the page is initially loaded?

EDIT: Corrected question. Issue only occurred after following internal links, not any links.

Natalie Chouinard
  • 1,472
  • 1
  • 10
  • 15

2 Answers2

62

The problem was that Trello uses HTML5's pushState for page transitions, so the content script wasn't always being run after a board was opened.

Solution

Changes to manifest:

{
  "manifest_version": 2,

  "name": "Temp Ext",
  "version": "1.1",

  "content_scripts": [{
    "matches": ["*://trello.com/*"],
    "js":["contentscript.js"]
  }],

  "background": {
    "scripts": ["background.js"]
  },

  "permissions": [
    "*://trello.com/*", "tabs", "webNavigation"
  ]
}

Add background script:

chrome.webNavigation.onHistoryStateUpdated.addListener(function(details) {
    chrome.tabs.executeScript(null,{file:"contentscript.js"});
});
Natalie Chouinard
  • 1,472
  • 1
  • 10
  • 15
  • 2
    This was very useful for me. GitHub does the same thing. My only difference was that I had to change the "matches": attribute in my manifest.json. Previously I was only loading by content script for `*://github.com/*/*.wiki`. I was catching the status push on a transition _out of_ a `github.com/*` page but since I had not loaded a wiki page I could not call the content script. I changed the `manifest.json` to ```"content_scripts": [ { "matches": ["*://github.com/*"], ...``` – PMorganCA Apr 15 '16 at 20:20
  • 2
    *finallllllllly*, a method that actually works. you don't know how long i've been searching for something like this. so many dud "solutions" out there – oldboy Jul 24 '17 at 07:48
  • Also works for me, but I needed it for Firefox. I changed it to: `browser.webNavigation.onHistoryStateUpdated.addListener(function(details) {browser.tabs.executeScript(null,{file:"contentscript.js"});});` And the `permissions` are important. I forgot to set them and got an undefined error. – Mike Nov 17 '17 at 18:14
  • 1
    Want to echo this solution is great. It strikes a nice balance between programatic and declarative content scripts. You can keep your declaratively injected content scripts for page reload events, which is great as they are easier to debug. Whilst also handling the on push edge case! – Christoph Hansen Dec 03 '20 at 00:56
0

It works perfectly for me. I created extension with two files you showed:

manifest.json:

{
  "manifest_version": 2,

  "name": "Temp Ext",
  "version": "1.0",

  "content_scripts": [
    {
      "matches": ["*://trello.com/b/*"],
      "js":["contentscript.js"]
    }
  ]
}

contentscript.js:

console.log("Hello, world!");

Then I open third link in this search thread: https://www.google.ca/search?q=trello+board+game&oq=trello+board+game&aqs=chrome..69i57.5037j0j1&sourceid=chrome&ie=UTF-8 ("Game of Thrones: the Board Game - Trello") and Chrome DevTools Console writes "Hello, world!"

gthacoder
  • 2,213
  • 3
  • 15
  • 17