Evan
Evan

Reputation: 345

Loading an asset stored within a chrome extension

Let's say I have a JSON file stored within my extension called settings.json. I can get the URL of the file using:

chrome.extension.getURL("settings.json");

But now that I have the URL, how do I actually load the contents of that file so I can JSON.parse it and use it? The reason I'm doing this is that there is a server component, and I want to make deployment and testing on multiple servers easier (dev, staging, production, etc.) Alternatively if there's a way to add custom attributes to the manifest.json and access them, that would also work.

Upvotes: 20

Views: 21182

Answers (3)

Chrysaloid
Chrysaloid

Reputation: 53

A modern solutions using web_accessible_resources and fetch.

manifest.json

{
    // ...
    "web_accessible_resources": [
        {
            "matches": ["<all_urls>"], // adjust if needed
            "resources": ["Test.json"]
        }
    ],
    // ...
}

content-script.js

function getResourceContent(fileName) {
    return fetch(chrome.runtime.getURL(fileName))
    .then(resp => resp.json()); // important line
}

// ...

// Use somewhere else in the script like this
(async () => {
    const content = await getResourceContent("Test.json");
    // Use the content here
})();

// or like this
getResourceContent("Test.json").then(content => {
    // Use the content here
});

Note on important line: for other types of files use appropriate handling methods (i.e. .text() for plain text files). See the docs for more information.

If you plan on having more files with useful content in your extension I suggest making your manifest more flexible so you won't have to modify when you add another file. Just create subfolder "resources" and put all the useful files there.

manifest.json

{
    // ...
    "web_accessible_resources": [
        {
            "matches": ["<all_urls>"], // adjust if needed
            "resources": ["resources/*"]
        }
    ],
    // ...
}

content-script.js

function getResourceContent(fileName) {
    return fetch(chrome.runtime.getURL(`resources/${fileName}`))
    .then(resp => resp.json());
}

Upvotes: 0

Bill S
Bill S

Reputation: 56

I can verify that requesting the resource from an XHR in the background page works as previously described. Just be sure to add 'self' to the connect-src portion of your content_security_policy.

Upvotes: 2

serg
serg

Reputation: 111255

If you make your setting.js look like:

var settings =  {"param":value,...};

Then you can just include it on a background page and use settings variable:

<script src="settings.js"></script>

If you want to have pure json in your file without assigning it to any variables then you can load it using XMLHttpRequest:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = handleStateChange; // Implemented elsewhere.
xhr.open("GET", chrome.extension.getURL('/config_resources/config.json'), true);
xhr.send();

or if you included jquery into your project:

$.getJSON(chrome.extension.getURL('/config_resources/config.json'), function(settings) {
  //..
});

(btw using chrome.extension.getURL is required only if you are accessing a file from a content script, otherwise you can just use relative path /config_resources/config.json)

Upvotes: 30

Related Questions