Why won't my javascript-append stylesheet load

I current am working on a project and I want to add the ability to add custom themes. I have a basic structure for a theme. Below is the basic structure of a theme and it’s location

| appdir
| - main.py
| - static
| - - themes
|- - - - themeName
|- - - - - theme.json
|- - - - - style.css
|- - - - - config.js 
|- templates
|- - index.html

here is the contents of config.js:

function load() {
  var r = document.querySelector(':root');
  
  $.getJSON('/static/themes/defualt/defualt.json', function(data) {
    var link = $("<link />",{
      rel: "stylesheet",
      href: data.custom-css-path
    })
    $('head').append(link);
    r.style.setProperty('--bgClr', data.background-color);
    r.style.setProperty('--txClr', data.text-color);
    r.style.setProperty('--uiClr', data.interface-color);
    r.style.setProperty('--olClr', data.outline-color);
    r.style.setProperty('--nlClr', data.navbar-item-color);
    r.style.setProperty('--avClr', data.active-color);
  });
  head.appendChild(link);
  
}

load();

When I run this script, It returns an exit code of 200, but doesn’t show even a 404 for the stylesheet nor shows the new styling.
How can I fix this?

[EDIT] Here is an updated version of the code (still doesn’t work)

var load = function() {
  $.getJSON('static/themes/default/default.json', function(data) {
    let theme = JSON.parse(data);      
    console.log(theme)
    root.style.setProperty('--bgClr', theme.backgroundColor);
    root.style.setProperty('--txClr', theme.textColor);
    root.style.setProperty('--uiClr', theme.interfaceColor);
    root.style.setProperty('--olClr', theme.outlineColor);
    root.style.setProperty('--nlClr', theme.navbarItemColor);
    root.style.setProperty('--avClr', theme.activeColor);
    $('head').append(`<link rel="stylesheet" type="text/css" href="${theme.customCssPath}">`);
  });
};

load();

This new code now does display an code 200 for my json, but refuses to print my json’s contents and does not show the new css file appended.

I don’t think link is defined here. I could be wrong, but I don’t believe it is.

Also, if you’re not linking a stylesheet and are rather just adding styles, you should probably use <style>.

1 Like

I set link at the top of the getJSON

1 Like

True, but head.appendChild(link); is not inside getJSON.

1 Like

should I put it there?

Probably, but I don’t mess with JS too much, so I’m not certain. The only thing I’m certain of is the fact that in it’s current position, it’s undefined.

There’s a typo in your code by here:

$.getJSON(‘/static/themes/defualt/defualt.json’, function(data)

I don’t know if defualt is the correct path you are using but that might be the case of your error.

Also, in JS, CSS variables should be written in kebab-case not camelCase. (CSS naming convention is to use kebab-case).

1 Like
$('head').append(link);

and

head.appendChild(link);

You seem to doubling up on attempting to append to the head, I would suggest just removing the second one because it it isn’t even inside the request callback function.

Are you getting errors in the console? If you haven’t checked, I suggest you do. You can’t use - in a variable name, if you want to use -, use a string as the property accessor like this: data["background-color"].

1 Like

link isn’t defined, although it could be because of JavaScript’s shady past. Basically, var is the old variable declarator, the new ones are let and const (nowadays, I would always consider it bad practice to use var). var used to work by putting everything in the global scope (let and const are both local scope and const is immutable for strings, numbers and booleans) so technically it could be defined, however this is jQuery making a get request, so because the callback function won’t be called immediately given a request will take some time, it shouldn’t be defined.

1 Like

This sadly did not help. I have edited the original post to include an updated version of my code

1 Like

I notice that you were setting CSS variables on a root object, but root was not defined anywhere in the code you posted. You can add a let root to your script to define the root and set it to the root element.

var load = function() {
  $.getJSON('static/themes/default/default.json', function(data) {
    let theme = data;      
    console.log(theme)
    let root = document.documentElement; //right here
    root.style.setProperty('--bgClr', theme.backgroundColor);
    root.style.setProperty('--txClr', theme.textColor);
    root.style.setProperty('--uiClr', theme.interfaceColor);
    root.style.setProperty('--olClr', theme.outlineColor);
    root.style.setProperty('--nlClr', theme.navbarItemColor);
    root.style.setProperty('--avClr', theme.activeColor);
    $('head').append(`<link rel="stylesheet" type="text/css" href="${theme.customCssPath}">`);
  });
};

Be sure to call the load() function after the HTML is fully loaded.

$(document).ready(function() {
  load();
});

1 Like

it returns 200 for the json and the config.js file but still doesn’t display the new css

What does default.json look like? If it has a key called custom-css-path, then instead of doing theme.customCssPath you should do theme["custom-css-path"]

here is default.json:

{
  "backgroundColor": "#282C34", 
  "textColor": "#ffffff",
  "interfaceColor": "#3b3c3f",
  "outlineColor": "#62656a",
  "navbarItemColor": "#55585e",
  "activeColor": "#009dff",
  
  "cohesiveBorderRadius": "0vmin",
  "customCssPath": "/static/themes/defualt/style.css",
  "jsThemeConfigPath": "/static/themes/defualt/config.js",
};

You have a typo in default there too

still doesn’t work tho

Try to remove your json.parse by changing let theme = JSON.parse to something like let theme = data;

Also after console.log(theme) make sure root is defined by adding var root = document.documentElement;

Also your JSON file has an unnecessary comma at the end in "jsThemeConfigPath": "/static/themes/defualt/config.js",

If this doens’t help try to check your browser for any errors.