Background Color on PWA

What I’m trying to do:
Keep the background color consistent on a PWA in the ‘safe zone’ and when scrolling beyond limits. Seems to be defaulting to the primary color of my color scheme.

What I’ve tried and what’s not working:
Doing stuff like this in my native libraries:

<meta name="theme-color" content="#FFFBFE">

<script>
document.querySelectorAll('[rel="manifest"]')[0].remove()
</script>

<link rel="manifest" href="_/theme/manifest.json">

Here’s some examples:

Here’s how it looks when I scroll down (pull up) beyond the scroll limit:

Here’s how it looks when I scroll up (pull down) beyond the scroll limit:

Found that the manifest.json is using the app’s primary color in two places:

{
    "start_url": "https://boilerplate.anvil.app/",
    "name": "Boilerplate",
    "short_name": "Boilerplate",
    "description": "This app is built with Anvil, the platform for building full-stack web apps quickly and robustly.",
    "background_color": "#6750A4",
    "theme_color": "#6750A4",
    "display": "standalone",
    "icons": [
        {
            "src": "https://anvil.works/icon-512x512.png",
            "sizes": "192x192",
            "type": "image\/png",
            "density": "2.0",
            "purpose": "any"
        },
        {
            "src": "https://anvil.works/icon-512x512.png",
            "sizes": "512x512",
            "type": "image\/png",
            "density": "2.0",
            "purpose": "any"
        },
        {
            "src": "https://anvil.works/icon-512x512.png",
            "sizes": "512x512",
            "type": "image\/png",
            "density": "2.0",
            "purpose": "maskable"
        }
    ]
}

Just can’t figure out how to change it…

1 Like

You can replace your existing manifest.json with a new one as shown here

I thought you couldn’t replace your existing manifest.json, so I spent some time coming up with this hacky approach.

I think @divyeshlakhotia 's approach is probably better, but here it is anyways:

First, change your Primary Colour in the Colour Scheme of your Theme to #FFFBFE .

Then use Javascript to update the default primary colour in your CSS on your website to the purple you are using. You can use Native Libraries for that using this code (replace #FF0000 with your hex code):

function updateCSSVariable(variablePattern, newValue) {
  // Get all style elements in the document
  var styleElements = document.querySelectorAll('style');

  // Iterate over each style element
  styleElements.forEach(function(styleElement) {
    // Get the text content of the style element
    var cssText = styleElement.textContent;
    // Define a regular expression pattern to match variables with the given pattern
      regex_pattern = '--' + variablePattern + '-\\w+:\\#[a-fA-F0-9]+'
      var regex = new RegExp(regex_pattern);

    // Find all matches of variables matching the pattern
    var matches = cssText.match(regex);
    console.log(matches)

    if (matches) {
      // Iterate over each match and update the variable
      matches.forEach(function(match) {
        // Extract the color part from the matched variable
        var colorPart = match.split(':')[1];
        // Replace the color part with the new value
        var newVariable = match.replace(colorPart, newValue);
        // Perform the replacement in the CSS text
        cssText = cssText.replace(match, newVariable);
      });

      // Apply the updated CSS text to the style element
      styleElement.textContent = cssText;
    }
  });
}
updateCSSVariable('anvil-color-Primary-500', '#FF0000');

This way you can keep on using the Primary Color variable in your app, while also making sure the manifest uses your white background instead of purple.

Thanks @APDW for the workaround - haven’t tested it but found the issue:

It turns out the problem @divyeshlakhotia is actually not with the manifest.json, it is with this line in the head tag:

<meta name="theme-color" content="#6750A4">

Adding another ‘theme-color’ meta tag didn’t fix the issue. I had to remove this meta tag first:

<script>
document.addEventListener('DOMContentLoaded', (event) => {
  // Attempt to find an existing theme-color meta tag
  var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');

  if (themeColorMetaTag) {
    // If found, update its content attribute to the new color
    themeColorMetaTag.setAttribute('content', '#FFFBFE');
    console.log("Theme color updated to #FFFBFE.");
  } else {
    // If not found, create a new meta tag for theme-color
    themeColorMetaTag = document.createElement('meta');
    themeColorMetaTag.name = 'theme-color';
    themeColorMetaTag.content = '#FFFBFE';
    document.head.appendChild(themeColorMetaTag);
    console.log("Theme color meta tag added with color #FFFBFE.");
  }
});
</script>

There is a split second where the background is my primary color before that script (in my native libraries) executes and fixes it. I guess that’s the best we can do for now.

The code below will do exaclty what you are looking for. I have spent a long time on
this issue and from my tests, it is instant loading of the desired color.

Add the following into your Native Libraries.

<meta name="theme-color" content="#000000">
  
<script defer>
        document.querySelector('meta[name="theme-color"]').setAttribute('content', '#000000');
</script>
3 Likes

So, I was also playing around with this and thought I’d share some extra context.

It is actually not the primary color that is being used for the PWA background, but whatever color is first in your color scheme (regardless of its name). The same is true for the spinner color.

So, another way to change PWA background color would be to change the order of the colors in your color scheme (e.g., put the ‘Background’ color on top).

The unwanted side effect of this is that will also change the spinner’s color. So @bdr997’s method would be preferable. Unless you have a custom spinner in which case it shouldn’t be an issue.

1 Like

Thanks for looking into this! Really helpful to know that as I am using a custom spinner.

Anywho I hope the Anvil team makes this “fixed” by default.

Then placing the background color at the top might work better for you actually.

For me bdr997’s method is still not quite instant - there is a split second where the PWA background color is the primary before it switches over.

But if you place the desired color at the top of your color scheme then it is instant.

I agree. It would be nice to have a bit more options for customizability rather than trying to “hack” it.