Skip to content

Commit

Permalink
offload loading to other components and use Suspense
Browse files Browse the repository at this point in the history
  • Loading branch information
probablyjassin committed Nov 25, 2024
1 parent c924e63 commit 0118b38
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 33 deletions.
11 changes: 11 additions & 0 deletions components/ContentLoader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<ContentDoc>
<template #not-found>
<div class="text-center py-16">
<h1 class="text-4xl font-bold mb-4">Document Not Found</h1>
<p class="text-lg mb-4">Sorry, the document you are looking for does not exist.</p>
<NuxtLink to="/" class="text-primary underline">Go back to the homepage</NuxtLink>
</div>
</template>
</ContentDoc>
</template>
31 changes: 31 additions & 0 deletions components/RelatedPosts.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
<section v-if="postsState?.length" class="mt-8">
<h2 class="text-2xl font-bold mb-4">Did you also read these? 👀</h2>
<ul>
<li v-for="post in shuffled(postsState.filter((p) => p._path !== $route.path).slice(0, 3))"
:key="post._path">
<NuxtLink :to="post._path" class="text-primary underline">{{ post.title }}</NuxtLink>
</li>
</ul>
</section>
</template>

<script setup lang="ts">
interface BlogPost {
_path: string;
title: string;
description?: string;
image?: string;
date?: string;
_file: string;
_dir: string;
}
const postsState = useState<BlogPost[]>("posts", () => []);
const shuffled = <T>(items: T[]): T[] =>
items
.map((value: T) => ({ value, sort: Math.random() }))
.sort((a, b) => a.sort - b.sort)
.map(({ value }) => value);
</script>
52 changes: 19 additions & 33 deletions pages/blog/[...slug].vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,32 @@
<div>
<NuxtLayout>
<main>
<ContentDoc>
<template #not-found>
<div class="text-center py-16">
<h1 class="text-4xl font-bold mb-4">Document Not Found</h1>
<p class="text-lg mb-4">Sorry, the document you are looking for does not exist.</p>
<NuxtLink to="/" class="text-primary underline">Go back to the homepage</NuxtLink>
<Suspense>
<template #default>
<main>
<ContentLoader />
<hr />
<RelatedPosts v-if="showRelated" :current-path="$route.path" />
</main>
</template>
<template #fallback>
<div class="animate-pulse">
<div class="h-4 bg-[var(--text-200)] rounded w-3/4 mb-4"></div>
<div class="h-4 bg-[var(--text-200)] rounded w-1/2 mb-4"></div>
<div class="h-4 bg-[var(--text-200)] rounded w-2/3"></div>
</div>
</template>
</ContentDoc>
</Suspense>
</main>
<hr />
<section v-if="postsState?.length" class="mt-8">
<h2 class="text-2xl font-bold mb-4">Did you also read these? 👀</h2>
<ul>
<li v-for="post in shuffled(postsState.filter((p) => p._path !== $route.path).slice(0, 3))"
:key="post._path">
<NuxtLink :to="post._path" class="text-primary underline">{{ post.title }}</NuxtLink>
</li>
</ul>
</section>
</NuxtLayout>
</div>
</template>

<script setup lang="ts">
interface BlogPost {
_path: string;
title: string;
description?: string;
image?: string;
date?: string;
_file: string;
_dir: string;
}
const postsState = useState<BlogPost[]>("posts", () => []);
const showRelated = ref(false)
const shuffled = <T>(items: T[]): T[] =>
items
.map((value: T) => ({ value, sort: Math.random() }))
.sort((a, b) => a.sort - b.sort)
.map(({ value }) => value);
// Only show related posts after main content loads
onMounted(() => {
showRelated.value = true
})
</script>

0 comments on commit 0118b38

Please sign in to comment.