Tag: dashboard

Fetching and Parsing JSON with Vue 3

Let’s say you have a JSON endpoint (like a MikroTik switch status that you get from a script ). You want to see it graphically in your webbrowser . You don’t want to ear about npm or configure Webpack.
Here is the single-file solution. It uses Vue 3 from a CDN to fetch, parse, and render your JSON in real-time.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Switch Stats</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <style>
        body { background: #111; color: #ddd; font-family: monospace; padding: 20px; }
        /* Simple responsive grid for the ports */
        .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
        .card { border: 1px solid #444; padding: 10px; background: #222; }
        .green { color: #0f0; } .red { color: #f00; } .gold { color: #fd0; }
    </style>
</head>
<body>
    <div id="app">
        <div v-if="!device">Loading...</div>
        <div v-else>
            <h1>{{ device.general.identity }}</h1>
            <p>IP: {{ device.general.ip }} | CPU: {{ device.general.cpu }}%</p>
            <div class="grid">
                <div v-for="p in device.ethernet" :key="p.name" class="card">
                    <strong :class="p.up ? 'green' : 'red'">{{ p.name }}</strong>
                    <div v-if="p.up">
                        {{ p.speed }}
                        <div v-if="p.poe.power" class="gold">{{ p.poe.power }}W</div>
                        <div v-if="p.sfp.temperature">Temp: {{ p.sfp.temperature }}°C</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script>
        Vue.createApp({
            setup() {
                // Define a reactive container for our data
                const device = Vue.ref(null);
                const load = async () => {
                    // Fetch the local JSON file
                    // Note: This requires a local server (CORS) if not on the same domain
                    const res = await fetch('switch.json');                     
                    // Assigning the JSON to .value triggers the HTML update automatically
                    device.value = await res.json();
                };
                Vue.onMounted(() => {
                    load();
                    setInterval(load, 30000); // Auto-Refresh every 30s
                });
                return { device };
            }
        }).mount('#app');
    </script>
</body>
</html>

The Logic :

We use

const device = Vue.ref(null);

const load = async () => {
    const res = await fetch('data.json'); 
    device.value = await res.json(); // Reactivity triggers here
};

to load the json and put it in device then after this we return it to be used in the html part
then we can map the data we just got in device

  • Use v-for to iterate over arrays (like our Ethernet ports).
  • Use v-if to filter out empty data (like ports without PoE).

the demo is here https://www.d0wn.com/vue/
and the demo json file is here : https://www.d0wn.com/vue/switch.json

Because browsers block fetch requests to local files for security (CORS), you cannot just double-click index.html.

Run a temporary server in the folder containing your file

python3 -m http.server 8000

Then visit http://localhost:8000.