Skip to content

Commit 418f992

Browse files
authored
Merge pull request #14 from coderdiaz/feature/404-page
Added 404 not found page
2 parents 7d77c41 + aec62a6 commit 418f992

File tree

4 files changed

+123
-22
lines changed

4 files changed

+123
-22
lines changed

src/content.config.ts

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,29 @@ export const seoSchemaWithoutImage = z.object({
88
type: z.string().optional(),
99
keywords: z.string().optional(),
1010
canonicalUrl: z.string().optional(),
11-
twitter: z.object({
12-
creator: z.string().optional(),
13-
}).optional(),
11+
twitter: z
12+
.object({
13+
creator: z.string().optional(),
14+
})
15+
.optional(),
1416
robots: z.string().optional(),
15-
})
17+
});
1618

1719
const seoSchema = (image: ImageFunction) =>
18-
z.object({
19-
image: image().optional(),
20-
}).merge(seoSchemaWithoutImage);
20+
z
21+
.object({
22+
image: image().optional(),
23+
})
24+
.merge(seoSchemaWithoutImage);
2125

2226
const pageCollection = defineCollection({
2327
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: './src/content/pages' }),
24-
schema: ({ image }) => z.object({
25-
title: z.string(),
26-
seo: seoSchema(image),
27-
}),
28+
schema: ({ image }) =>
29+
z.object({
30+
title: z.string(),
31+
description: z.string().optional(),
32+
seo: seoSchema(image),
33+
}),
2834
});
2935

3036
const linkCollection = defineCollection({
@@ -61,12 +67,13 @@ const talkCollection = defineCollection({
6167

6268
const postCollection = defineCollection({
6369
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: './src/content/posts' }),
64-
schema: ({ image }) => z.object({
65-
title: z.string(),
66-
date: z.date(),
67-
image: image().optional(),
68-
seo: seoSchema(image),
69-
}),
70+
schema: ({ image }) =>
71+
z.object({
72+
title: z.string(),
73+
date: z.date(),
74+
image: image().optional(),
75+
seo: seoSchema(image),
76+
}),
7077
});
7178

7279
export const collections = {

src/content/pages/404.mdx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: 404 - Page not found
3+
description: Sorry, the page you are looking for doesn't exist or has been moved.
4+
seo:
5+
title: 404 - Page not found
6+
description: Sorry, the page you are looking for doesn't exist or has been moved.
7+
type: website
8+
robots: noindex, no follow
9+
---

src/pages/404.astro

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
import { getEntry } from 'astro:content';
3+
import BaseLayout from '@/layouts/BaseLayout.astro';
4+
import Container from '@/components/Container.astro';
5+
6+
const entry = await getEntry('pages', '404');
7+
---
8+
9+
<BaseLayout seo={entry?.data.seo}>
10+
<Container
11+
as="section"
12+
class="min-h-[calc(100vh-12rem)] flex items-center justify-center"
13+
>
14+
<div class="text-center space-y-8">
15+
<!-- 404 Number -->
16+
<div class="space-y-4">
17+
<h1 class="text-6xl md:text-8xl font-bold text-headings opacity-20">
18+
404
19+
</h1>
20+
<div class="space-y-2">
21+
<h2 class="text-2xl md:text-3xl font-medium text-headings">
22+
{entry?.data.title}
23+
</h2>
24+
<p class="text-muted-foreground max-w-md mx-auto">
25+
{entry?.data.description}
26+
</p>
27+
</div>
28+
</div>
29+
30+
<!-- Action Buttons -->
31+
<div
32+
class="flex flex-col sm:flex-row gap-4 justify-center items-center pt-4"
33+
>
34+
<a
35+
href="/"
36+
class="group inline-flex items-center justify-center px-6 py-3 bg-headings text-background font-medium rounded-full transition-all duration-200 hover:bg-headings/90 hover:scale-105 focus:outline-none focus:ring-2 focus:ring-headings/50 focus:ring-offset-2 focus:ring-offset-background min-w-[140px]"
37+
>
38+
<svg
39+
class="w-4 h-4 mr-2 transition-transform group-hover:-translate-x-1"
40+
fill="none"
41+
stroke="currentColor"
42+
viewBox="0 0 24 24"
43+
>
44+
<path
45+
stroke-linecap="round"
46+
stroke-linejoin="round"
47+
stroke-width="2"
48+
d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
49+
</svg>
50+
Go Home
51+
</a>
52+
53+
<a
54+
href="/writing"
55+
class="group inline-flex items-center justify-center px-6 py-3 border border-border text-headings font-medium rounded-full transition-all duration-200 hover:bg-muted-foreground/10 hover:border-headings/30 focus:outline-none focus:ring-2 focus:ring-headings/50 focus:ring-offset-2 focus:ring-offset-background min-w-[140px]"
56+
>
57+
Browse Writing
58+
<svg
59+
class="w-4 h-4 ml-2 transition-transform group-hover:translate-x-1"
60+
fill="none"
61+
stroke="currentColor"
62+
viewBox="0 0 24 24"
63+
>
64+
<path
65+
stroke-linecap="round"
66+
stroke-linejoin="round"
67+
stroke-width="2"
68+
d="M14 5l7 7m0 0l-7 7m7-7H3"></path>
69+
</svg>
70+
</a>
71+
</div>
72+
73+
<!-- Additional Help Text -->
74+
<p class="text-sm text-muted-foreground/70 pt-8">
75+
If you believe this is an error, please check the URL or try refreshing
76+
the page.
77+
</p>
78+
</div>
79+
</Container>
80+
</BaseLayout>

src/pages/index.astro

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import Talk from '@/components/ui/Talk.astro';
99
import { sortJobsByDate } from '@/lib/utils';
1010
1111
const entry = await getEntry('pages', 'homepage');
12+
13+
if (!entry) {
14+
throw new Error('Homepage entry not found');
15+
}
16+
1217
const { Content } = await render(entry);
1318
1419
const links = await getCollection('links');
@@ -18,11 +23,11 @@ const talks = await getCollection('talks');
1823
---
1924

2025
<BaseLayout seo={entry.data.seo}>
21-
<Container as='section' class='py-6'>
26+
<Container as="section" class="py-6">
2227
<Author {...DEFAULT_CONFIGURATION.author} />
2328
</Container>
2429

25-
<Container as='section' class='py-6'>
30+
<Container as="section" class="py-6">
2631
<div class="flex flex-col gap-6">
2732
<div class="flex items-center">
2833
<span class="text-headings">About</span>
@@ -34,7 +39,7 @@ const talks = await getCollection('talks');
3439
</Container>
3540
{
3641
links.length > 0 && (
37-
<Container as='section' class='py-8'>
42+
<Container as="section" class="py-8">
3843
<div class="flex flex-col gap-5">
3944
<span class="text-headings">Contact</span>
4045
<ul class="flex flex-col gap-3">
@@ -62,7 +67,7 @@ const talks = await getCollection('talks');
6267
}
6368
{
6469
sortedJobs.length > 0 && (
65-
<Container as='section' class='py-6'>
70+
<Container as="section" class="py-6">
6671
<div class="flex flex-col gap-5">
6772
<span class="text-headings">Work Experience</span>
6873
<ul class="flex flex-col gap-8">
@@ -76,7 +81,7 @@ const talks = await getCollection('talks');
7681
}
7782
{
7883
talks.length > 0 && (
79-
<Container as='section' class='py-6'>
84+
<Container as="section" class="py-6">
8085
<div class="flex flex-col gap-5">
8186
<span class="text-headings">Speaking</span>
8287
<ul class="flex flex-col gap-8">

0 commit comments

Comments
 (0)