JavaScript and StorageManager

JavaScript and StorageManager

This article explains JavaScript and StorageManager.

We will explain the features of StorageManager in detail, and introduce how to use it step by step with code examples that actually work in the browser.

YouTube Video

javascript-storage-manager.html
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4  <meta charset="UTF-8">
  5  <title>JavaScript &amp; HTML</title>
  6  <style>
  7    * {
  8        box-sizing: border-box;
  9    }
 10
 11    body {
 12        margin: 0;
 13        padding: 1em;
 14        padding-bottom: 10em;
 15        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 16        background-color: #f7f9fc;
 17        color: #333;
 18        line-height: 1.6;
 19    }
 20
 21    .container {
 22        max-width: 800px;
 23        margin: 0 auto;
 24        padding: 1em;
 25        background-color: #ffffff;
 26        border: 1px solid #ccc;
 27        border-radius: 10px;
 28        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 29    }
 30
 31    .container-flex {
 32        display: flex;
 33        flex-wrap: wrap;
 34        gap: 2em;
 35        max-width: 1000px;
 36        margin: 0 auto;
 37        padding: 1em;
 38        background-color: #ffffff;
 39        border: 1px solid #ccc;
 40        border-radius: 10px;
 41        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 42    }
 43
 44    .left-column, .right-column {
 45        flex: 1 1 200px;
 46        min-width: 200px;
 47    }
 48
 49    h1, h2 {
 50        font-size: 1.2rem;
 51        color: #007bff;
 52        margin-top: 0.5em;
 53        margin-bottom: 0.5em;
 54        border-left: 5px solid #007bff;
 55        padding-left: 0.6em;
 56        background-color: #e9f2ff;
 57    }
 58
 59    button {
 60        display: block;
 61        margin: 1em auto;
 62        padding: 0.75em 1.5em;
 63        font-size: 1rem;
 64        background-color: #007bff;
 65        color: white;
 66        border: none;
 67        border-radius: 6px;
 68        cursor: pointer;
 69        transition: background-color 0.3s ease;
 70    }
 71
 72    button:hover {
 73        background-color: #0056b3;
 74    }
 75
 76    #output {
 77        margin-top: 1em;
 78        background-color: #1e1e1e;
 79        color: #0f0;
 80        padding: 1em;
 81        border-radius: 8px;
 82        min-height: 200px;
 83        font-family: Consolas, monospace;
 84        font-size: 0.95rem;
 85        overflow-y: auto;
 86        white-space: pre-wrap;
 87    }
 88
 89    .highlight {
 90        outline: 3px solid #ffc107; /* yellow border */
 91        background-color: #fff8e1;  /* soft yellow background */
 92        transition: background-color 0.3s ease, outline 0.3s ease;
 93    }
 94
 95    .active {
 96        background-color: #28a745; /* green background */
 97        color: #fff;
 98        box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
 99        transition: background-color 0.3s ease, box-shadow 0.3s ease;
100    }
101  </style>
102</head>
103<body>
104    <div class="container">
105        <h1>JavaScript Console</h1>
106        <button id="executeBtn">Execute</button>
107        <div id="output"></div>
108    </div>
109
110    <script>
111        // Override console.log to display messages in the #output element
112        (function () {
113            // Override console.log
114            const originalLog = console.log;
115            console.log = function (...args) {
116                originalLog.apply(console, args);
117                const message = document.createElement('div');
118                message.textContent = args
119                    .map(arg => (typeof arg === "object" && arg !== null ? JSON.stringify(arg) : String(arg)))
120                    .join(" ");
121                output.appendChild(message);
122            };
123
124            // Override console.error
125            const originalError = console.error;
126            console.error = function (...args) {
127                originalError.apply(console, args);
128                const message = document.createElement('div');
129                message.textContent = args
130                    .map(arg => (typeof arg === "object" && arg !== null ? JSON.stringify(arg) : String(arg)))
131                    .join(" ");
132                message.style.color = 'red'; // Color error messages red
133                output.appendChild(message);
134            };
135        })();
136
137        document.getElementById('executeBtn').addEventListener('click', () => {
138            // Prevent multiple loads
139            if (document.getElementById('externalScript')) return;
140
141            const script = document.createElement('script');
142            script.src = 'javascript-storage-manager.js';
143            script.id = 'externalScript';
144            //script.onload = () => console.log('javascript-storage-manager.js loaded and executed.');
145            //script.onerror = () => console.log('Failed to load javascript-storage-manager.js.');
146            document.body.appendChild(script);
147        });
148    </script>
149</body>
150</html>

JavaScript and StorageManager

Web storage features like localStorage and IndexedDB in browsers are essential for saving the state and data of applications locally on the user's device. However, if information about storage capacity management and persistence is insufficient, unexpected data loss may occur.

StorageManager is an API provided by user agents (mainly browsers) that offers ways to obtain and manage information on the usage and persistence of storage.

What is StorageManager?

StorageManager is an object accessible via navigator.storage, providing the following main features:.

  • Retrieve information on used and available storage (navigator.storage.estimate())
  • Check the persistence status of storage (navigator.storage.persisted())
  • Request storage persistence (navigator.storage.persist())

This is especially useful if you want to ensure persistent storage in Service Workers or PWAs (Progressive Web Apps).

Checking Availability

First, check whether the browser supports StorageManager.

1if ('storage' in navigator && 'estimate' in navigator.storage) {
2    console.log("StorageManager is supported.");
3} else {
4    console.warn("StorageManager is not supported in this browser.");
5}
  • You can determine support by checking if the navigator.storage object exists and contains the estimate method.

Retrieving Storage Usage

By using navigator.storage.estimate(), you can get the storage your app is using as well as the total storage quota.

 1async function showStorageUsage() {
 2    if (!navigator.storage || !navigator.storage.estimate) {
 3        console.warn("StorageManager is not supported.");
 4        return;
 5    }
 6
 7    const { usage, quota } = await navigator.storage.estimate();
 8    console.log(`Used: ${(usage / 1024 / 1024).toFixed(2)} MB`);
 9    console.log(`Total: ${(quota / 1024 / 1024).toFixed(2)} MB`);
10    console.log(`Usage percentage: ${(usage / quota * 100).toFixed(2)}%`);
11}
12
13showStorageUsage();
  • usage represents the current usage in bytes, and quota is the maximum available capacity. You can monitor the storage usage to notify the user if your app is approaching the storage limit, among other uses.

Checking Storage Persistence

In many browsers, storage is saved as 'temporary', which means it may be automatically deleted if the disk space becomes insufficient. By using the persisted() method, you can check whether the current storage is persistent.

1async function checkPersistence() {
2    const isPersisted = await navigator.storage.persisted();
3    console.log(`Persistent storage: ${isPersisted ? "Yes" : "No"}`);
4}
5
6checkPersistence();

Requesting Storage Persistence

If it is not already persistent, you can request persistence from the browser using persist(). However, it may be denied depending on explicit user actions or certain conditions.

1async function requestPersistence() {
2    const granted = await navigator.storage.persist();
3    console.log(`Persistence request ${granted ? "granted" : "denied"}`);
4}
5
6requestPersistence();

In many browsers, satisfying the following conditions increases the likelihood of getting persistence approval:.

  • The app is installed as a PWA
  • The user frequently uses the app
  • The app is running in an HTTPS environment
  • The persistence request is tied to an explicit user action, such as a click

Practical Example: Requesting Persistence from the User When Not Persisted

 1async function ensurePersistence() {
 2    const isPersisted = await navigator.storage.persisted();
 3    if (isPersisted) {
 4        console.log("Already using persistent storage.");
 5        return;
 6    }
 7
 8    const granted = await navigator.storage.persist();
 9    if (granted) {
10        alert("Storage has been set to persistent.");
11    } else {
12        alert("Unable to set persistent storage. Your data may be deleted.");
13    }
14}
15
16document.querySelector("#persistButton").addEventListener("click", ensurePersistence);
  • In this example, persistence is requested when the user clicks a button. Using a button makes the request within the context of a user action, making it more likely to be granted.

Cautions and Compatibility

  • navigator.storage is only available in HTTPS environments.
  • Major browsers (Chrome, Edge, Firefox) support it, but some features are limited in Safari.
  • quota depends on the storage conditions of the device, and may have different values on different devices for the same site.

Summary

By using StorageManager, web applications can use the user's local storage more safely and strategically. It mainly provides the following features:.

  • You can check storage usage with estimate().
  • You can check the persistence status with persisted().
  • You can request persistence with persist().

When developing PWAs or offline-first apps, utilizing StorageManager allows you to achieve both improved user experience and enhanced data protection.

You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.

YouTube Video