diff --git a/front/src/components/About.vue b/front/src/components/About.vue
index 72355ef58..6e2bf9815 100644
--- a/front/src/components/About.vue
+++ b/front/src/components/About.vue
@@ -21,7 +21,7 @@ const banner = computed(() => get(nodeinfo.value, 'metadata.banner'))
 const shortDescription = computed(() => get(nodeinfo.value, 'metadata.shortDescription'))
 
 const stats = computed(() => {
-  const users = get(nodeinfo.value, 'usage.users.activeMonth', null)
+  const users = get(nodeinfo.value, 'usage.users.activeMonth', 0)
   const hours = get(nodeinfo.value, 'metadata.library.music.hours', 0)
 
   if (users === null) {
@@ -32,7 +32,7 @@ const stats = computed(() => {
 })
 
 const openRegistrations = computed(() => get(nodeinfo.value, 'openRegistrations'))
-const defaultUploadQuota = computed(() => humanSize(get(nodeinfo.value, 'metadata.defaultUploadQuota') * 1000 * 1000))
+const defaultUploadQuota = computed(() => humanSize(get(nodeinfo.value, 'metadata.defaultUploadQuota', 0) * 1000 * 1000))
 
 const headerStyle = computed(() => {
   if (!banner.value) {
@@ -196,11 +196,11 @@ const headerStyle = computed(() => {
                       
                       
                         
-                          {{ parseInt(stats.hours).toLocaleString($store.state.ui.momentLocale) }}
+                          {{ stats.hours.toLocaleString($store.state.ui.momentLocale) }}
                           
                           hour of music
                         
diff --git a/front/src/components/AboutPod.vue b/front/src/components/AboutPod.vue
index ae26a67b4..9a0eabb6a 100644
--- a/front/src/components/AboutPod.vue
+++ b/front/src/components/AboutPod.vue
@@ -8,6 +8,7 @@ import { computed } from 'vue'
 import axios from 'axios'
 
 import useMarkdown from '~/composables/useMarkdown'
+import type { NodeInfo } from '~/store/instance'
 
 const store = useStore()
 const nodeinfo = computed(() => store.state.instance.nodeinfo)
@@ -25,9 +26,9 @@ const labels = computed(() => ({
 
 const podName = computed(() => get(nodeinfo.value, 'metadata.nodeName') || 'Funkwhale')
 const banner = computed(() => get(nodeinfo.value, 'metadata.banner'))
-const longDescription = useMarkdown(() => get(nodeinfo.value, 'metadata.longDescription'))
-const rules = useMarkdown(() => get(nodeinfo.value, 'metadata.rules'))
-const terms = useMarkdown(() => get(nodeinfo.value, 'metadata.terms'))
+const longDescription = useMarkdown(() => get(nodeinfo.value, 'metadata.longDescription', ''))
+const rules = useMarkdown(() => get(nodeinfo.value, 'metadata.rules', ''))
+const terms = useMarkdown(() => get(nodeinfo.value, 'metadata.terms', ''))
 const contactEmail = computed(() => get(nodeinfo.value, 'metadata.contactEmail'))
 const anonymousCanListen = computed(() => get(nodeinfo.value, 'metadata.library.anonymousCanListen'))
 const allowListEnabled = computed(() => get(nodeinfo.value, 'metadata.allowList.enabled'))
@@ -39,17 +40,19 @@ const federationEnabled = computed(() => get(nodeinfo.value, 'metadata.library.f
 const onDesktop = computed(() => window.innerWidth > 800)
 
 const stats = computed(() => {
+  const info = nodeinfo.value ?? {} as NodeInfo
+
   const data = {
-    users: get(nodeinfo.value, 'usage.users.activeMonth', null),
-    hours: get(nodeinfo.value, 'metadata.library.music.hours', null),
-    artists: get(nodeinfo.value, 'metadata.library.artists.total', null),
-    albums: get(nodeinfo.value, 'metadata.library.albums.total', null),
-    tracks: get(nodeinfo.value, 'metadata.library.tracks.total', null),
-    listenings: get(nodeinfo.value, 'metadata.usage.listenings.total', null)
+    users: get(info, 'usage.users.activeMonth', null),
+    hours: get(info, 'metadata.library.music.hours', null),
+    artists: get(info, 'metadata.library.artists.total', null),
+    albums: get(info, 'metadata.library.albums.total', null),
+    tracks: get(info, 'metadata.library.tracks.total', null),
+    listenings: get(info, 'metadata.usage.listenings.total', null)
   }
 
   if (data.users === null || data.artists === null) {
-    return
+    return data
   }
 
   return data
@@ -375,11 +378,11 @@ const headerStyle = computed(() => {
                     class="statistics-statistic"
                   >
                     
-                      {{ parseInt(stats.hours).toLocaleString($store.state.ui.momentLocale) }}
+                      {{ stats.hours.toLocaleString($store.state.ui.momentLocale) }}
                       
                       hour of music
                     
diff --git a/front/src/components/Home.vue b/front/src/components/Home.vue
index a44619bbd..7db516aa3 100644
--- a/front/src/components/Home.vue
+++ b/front/src/components/Home.vue
@@ -23,7 +23,7 @@ const nodeinfo = computed(() => store.state.instance.nodeinfo)
 const podName = computed(() => get(nodeinfo.value, 'metadata.nodeName') || 'Funkwhale')
 const banner = computed(() => get(nodeinfo.value, 'metadata.banner'))
 const shortDescription = computed(() => get(nodeinfo.value, 'metadata.shortDescription'))
-const longDescription = useMarkdown(() => get(nodeinfo.value, 'metadata.longDescription'))
+const longDescription = useMarkdown(() => get(nodeinfo.value, 'metadata.longDescription', ''))
 const rules = computed(() => get(nodeinfo.value, 'metadata.rules'))
 const contactEmail = computed(() => get(nodeinfo.value, 'metadata.contactEmail'))
 const anonymousCanListen = computed(() => get(nodeinfo.value, 'metadata.library.anonymousCanListen'))
@@ -31,7 +31,7 @@ const openRegistrations = computed(() => get(nodeinfo.value, 'openRegistrations'
 const defaultUploadQuota = computed(() => get(nodeinfo.value, 'metadata.defaultUploadQuota'))
 
 const stats = computed(() => {
-  const users = get(nodeinfo.value, 'usage.users.activeMonth', null)
+  const users = get(nodeinfo.value, 'usage.users.activeMonth', 0)
   const hours = get(nodeinfo.value, 'metadata.library.music.hours', 0)
 
   if (users === null) {
@@ -172,8 +172,8 @@ whenever(() => store.state.auth.authenticated, () => {
                   
                     
                       %{ count } hour of music
diff --git a/front/src/store/instance.ts b/front/src/store/instance.ts
index 72341bf5e..e446953b0 100644
--- a/front/src/store/instance.ts
+++ b/front/src/store/instance.ts
@@ -10,10 +10,77 @@ export interface State {
   frontSettings: FrontendSettings
   instanceUrl?: string
   knownInstances: string[]
-  nodeinfo: unknown | null
+  nodeinfo: NodeInfo | null
   settings: Settings
 }
 
+type TotalCount = {
+  total: number
+}
+
+export interface NodeInfo {
+  version: string;
+  software: {
+    name: string;
+    version: string;
+  }
+  protocols: any[];
+  services?: {
+    inbound?: string[];
+    outbound?: string[];
+  }
+  openRegistrations: boolean;
+  usage: {
+    users: {
+      total: number;
+      activeHalfyear: number;
+      activeMonth: number;
+    }
+  }
+  metadata: {
+    actorId: string
+    'private': boolean
+    shortDescription: string
+    longDescription: string
+    rules: string
+    contactEmail: string
+    terms: string
+    nodeName: string
+    banner: string
+    defaultUploadQuota: number
+    library: {
+      federationEnabled: boolean
+      anonymousCanListen: boolean
+      tracks?: TotalCount
+      artists?: TotalCount
+      albums?: TotalCount
+      music?: { hours: number }
+    }
+    supportedUploadExtensions: string[]
+    allowList: {
+      enabled: boolean
+      domains: string[]
+    }
+    reportTypes: {
+      'type': string
+      label: string
+      anonymous: boolean
+    }[]
+    funkwhaleSupportMessageEnabled: boolean
+    instanceSupportMessage: string
+    endpoints: {
+      knownNodes?: string
+      channels?: string
+      libraries?: string
+    }
+    usage: {
+      favorites: { tracks: TotalCount }
+      listenings: TotalCount
+      downloads: TotalCount
+    }
+  }
+}
+
 interface FrontendSettings {
   defaultServerUrl: string
   additionalStylesheets: string[]