Nuxt component for Openstatus public widget
Published on 5th October 2023
Openstatus has added a public endpoint where you can access the status of your status page. However, there's no SDK or package to integrate the status into your project right now.
Here, I'm giving components for Nuxt 2 and Nuxt 3 projects.
Component for Nuxt 3
<template>
<a
class="inline-flex gap-2 items-center px-3 py-1 text-sm rounded-md border border-border text-white/70 hover:bg-muted hover:text-white max-w-fit"
:href="statusSiteUrl"
target="_blank"
rel="noreferrer"
>
<span class="flex relative w-2 h-2">
<span
v-if="status.label === 'Operational'"
class="inline-flex absolute w-full h-full rounded-full opacity-75 duration-1000 animate-ping"
:class="status.color"
/>
<span
class="inline-flex relative w-2 h-2 rounded-full"
:class="status.color"
/>
</span>
{{ status.label }}
</a>
</template>
<script setup lang="ts">
import * as z from "zod";
const config = useRuntimeConfig();
const statusSiteUrl = config.statusSiteSlug;
const status = ref({
label: "checking",
color: undefined,
});
const statusEnum = z.enum([
"operational",
"degraded_performance",
"partial_outage",
"major_outage",
"under_maintenance",
"unknown",
]);
const statusSchema = z.object({ status: statusEnum });
const dictionary = {
operational: {
label: "Operational",
color: "bg-green-500",
},
degraded_performance: {
label: "Degraded Performance",
color: "bg-yellow-500",
},
partial_outage: {
label: "Partial Outage",
color: "bg-yellow-500",
},
major_outage: {
label: "Major Outage",
color: "bg-red-500",
},
unknown: {
label: "Unknown",
color: "bg-gray-500",
},
under_maintenance: {
label: "Under Maintenance",
color: "bg-gray-500",
},
} as const;
const { data } = await useFetch("/api/site-status");
const parsed = statusSchema.safeParse(data);
const key = !parsed.success ? "unknown" : parsed.data.status;
status.value = dictionary[key];
</script>
Component for Nuxt 2
<template>
<a
class="inline-flex gap-2 items-center px-3 py-1 text-sm rounded-md border border-border text-white/70 hover:bg-muted hover:text-white max-w-fit"
:href="statusSiteUrl"
target="_blank"
rel="noreferrer"
>
<span class="flex relative w-2 h-2">
<span
v-if="status.label === 'Operational'"
class="inline-flex absolute w-full h-full rounded-full opacity-75 duration-1000 animate-ping"
:class="status.color"
/>
<span
class="inline-flex relative w-2 h-2 rounded-full"
:class="status.color"
/>
</span>
{{ status.label }}
</a>
</template>
<script>
const statusEnum = [
"operational",
"degraded_performance",
"partial_outage",
"major_outage",
"under_maintenance",
"unknown",
];
const dictionary = {
operational: {
label: "Operational",
color: "bg-green-500",
},
degraded_performance: {
label: "Degraded Performance",
color: "bg-yellow-500",
},
partial_outage: {
label: "Partial Outage",
color: "bg-yellow-500",
},
major_outage: {
label: "Major Outage",
color: "bg-red-500",
},
unknown: {
label: "Unknown",
color: "bg-gray-500",
},
under_maintenance: {
label: "Under Maintenance",
color: "bg-gray-500",
},
};
export default {
data() {
return {
status: {
label: "Checking",
color: "",
},
statusSiteUrl: "read-from-runtime-config",
};
},
mounted() {
this.fetchSiteStatus();
},
methods: {
async fetchSiteStatus() {
const { data } = await $fetch((`/api/site-status`);
const key = statusEnum.includes(data.status) ? data.status : "unknown";
this.status = dictionary[key];
},
},
};
</script>
Serverless function to fetch status from Openstatus public API
export default defineEventHandler((event) => {
const config = useRuntimeConfig();
const resp = await $fetch(
`https://api.openstatus.dev/public/status/${config.statusSiteSlug}`,
{
next: { revalidate: 60 }, // cache request for 60 seconds
}
);
return response.status(200).json(resp.data);
})
You can find the code snippets in notion as well: Openstatus public widget snippets
Link to main documentation of Openstatus: Openstatus Docs