Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ export default defineConfig({
es: 'es-MX',
},
},
serialize(item) {
// Add lastmod to all sitemap entries
// For blog posts, this will be updated by the build process
// Static pages get the build date
item.lastmod = new Date().toISOString();
return item;
},
}),
],
site: "https://angel-baez.com/",
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@baezor/website",
"type": "module",
"version": "0.20.0",
"version": "0.21.0",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
Expand Down
79 changes: 41 additions & 38 deletions src/components/BaseHead.astro
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface Props {
image?: string | ImageMetadata;
keywords?: string[];
lang: Language;
ogType?: 'website' | 'article';
}

const defaultKeywords = ["Angel Baez", "angel-baez.com", "Full Stack Developer", "Entrepreneur", "Cancun", "Mexico", "baezor", "Web Developer"];
Expand All @@ -20,7 +21,8 @@ const {
description,
image = defaultSocialCard,
keywords,
lang
lang,
ogType = 'website'
} = Astro.props;

// Handle image URL (string or imported image)
Expand All @@ -39,6 +41,41 @@ const canonicalURL = new URL(Astro.url.pathname, SITE_URL);
// Generate alternate URLs for hreflang using centralized utility
const enUrl = new URL(getLocalizedUrl(Astro.url.pathname, 'en'), SITE_URL);
const esUrl = new URL(getLocalizedUrl(Astro.url.pathname, 'es'), SITE_URL);

// Structured Data schemas
const websiteSchema = {
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Angel Baez",
"alternateName": ["angel-baez.com", "baezor"],
"url": SITE_URL,
"inLanguage": ["en", "es"]
};

const personSchema = {
"@context": "https://schema.org",
"@type": "Person",
"name": "Angel Baez",
"url": SITE_URL,
"image": imageUrl.toString(),
"email": "angel@romerobaez.com",
"jobTitle": "Full Stack Developer and Entrepreneur",
"description": "Full Stack Developer and entrepreneur based in Cancun, Mexico",
"address": {
"@type": "PostalAddress",
"addressLocality": "Cancun",
"addressRegion": "Quintana Roo",
"addressCountry": "Mexico"
},
"sameAs": [
"https://www.linkedin.com/in/angelromerobaez",
"https://github.com/baezor/",
"https://www.instagram.com/baez0r/",
"https://www.facebook.com/baezor/",
"https://x.com/baezor/"
],
"knowsLanguage": ["en", "es"]
};
---

<!-- Essential Meta Tags -->
Expand All @@ -60,7 +97,7 @@ const esUrl = new URL(getLocalizedUrl(Astro.url.pathname, 'es'), SITE_URL);
<meta name="robots" content="index, follow" />

<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:type" content={ogType} />
<meta property="og:url" content={canonicalURL} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
Expand All @@ -78,41 +115,7 @@ const esUrl = new URL(getLocalizedUrl(Astro.url.pathname, 'es'), SITE_URL);
<meta name="twitter:creator" content="@baezor" />

<!-- Structured Data for WebSite -->
<script is:inline define:vars={{ siteUrl: SITE_URL }} type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Angel Baez",
"alternateName": ["angel-baez.com", "baezor"],
"url": siteUrl,
"inLanguage": ["en", "es"]
}
</script>
<script type="application/ld+json" set:html={JSON.stringify(websiteSchema)} />

<!-- Structured Data for Person -->
<script is:inline define:vars={{ siteUrl: SITE_URL, schemaImageUrl: imageUrl.toString() }} type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"name": "Angel Baez",
"url": siteUrl,
"image": schemaImageUrl,
"email": "angel@romerobaez.com",
"jobTitle": "Full Stack Developer and Entrepreneur",
"description": "Full Stack Developer and entrepreneur based in Cancun, Mexico",
"address": {
"@type": "PostalAddress",
"addressLocality": "Cancun",
"addressRegion": "Quintana Roo",
"addressCountry": "Mexico"
},
"sameAs": [
"https://www.linkedin.com/in/angelromerobaez",
"https://github.com/baezor/",
"https://www.instagram.com/baez0r/",
"https://www.facebook.com/baezor/",
"https://x.com/baezor/"
],
"knowsLanguage": ["en", "es"]
}
</script>
<script type="application/ld+json" set:html={JSON.stringify(personSchema)} />
26 changes: 12 additions & 14 deletions src/components/BreadcrumbSchema.astro
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,17 @@ interface Props {

const { items } = Astro.props;

// Build the breadcrumb list with position
const breadcrumbList = items.map((item, index) => ({
"@type": "ListItem",
"position": index + 1,
"name": item.name,
"item": new URL(item.url, SITE_URL).toString()
}));
// Build the breadcrumb schema
const breadcrumbSchema = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": items.map((item, index) => ({
"@type": "ListItem",
"position": index + 1,
"name": item.name,
"item": new URL(item.url, SITE_URL).toString()
}))
};
---

<script is:inline define:vars={{ breadcrumbList }} type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": breadcrumbList
}
</script>
<script type="application/ld+json" set:html={JSON.stringify(breadcrumbSchema)} />
3 changes: 0 additions & 3 deletions src/components/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ const isActive = (path: string) => {
<li>
<a href={getRelativeLocaleUrl(lang, 'about')} class={isActive("/about") || isActive("/es/about") ? "active" : ""}>{t('nav.about')}</a>
</li>
<li>
<a href={getRelativeLocaleUrl(lang, 'run')} class={isActive("/run") || isActive("/es/run") ? "active" : ""}>{t('nav.run')}</a>
</li>
<li>
<a href={getRelativeLocaleUrl(lang, 'contact')} class={isActive("/contact") || isActive("/es/contact") ? "active" : ""}
>{t('nav.contact')}</a
Expand Down
4 changes: 2 additions & 2 deletions src/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ export const SITE_TITLE = {
} as const;

export const SITE_DESCRIPTION = {
en: "Angel Baez - Full Stack Developer and entrepreneur",
es: "Angel Baez - Desarrollador Full Stack y emprendedor",
en: "Angel Baez - Full Stack Developer and entrepreneur based in Cancun, Mexico. Building web apps with TypeScript, React, and Node.js. Explore my blog for tutorials and insights.",
es: "Angel Baez - Desarrollador Full Stack y emprendedor en Cancún, México. Creando aplicaciones web con TypeScript, React y Node.js. Explora mi blog para tutoriales e insights.",
} as const;

export const SITE_URL = "https://angel-baez.com";
Expand Down
2 changes: 1 addition & 1 deletion src/content/blog/implementing-a-queue-in-typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Implementing a Queue in TypeScript"
description: "Implementing a queue in TypeScript"
pubDate: 2024-07-14T10:00:00.000Z
categories:
- TypeScript
- typescript
- data-structures
metaDescription: "Build a queue data structure from scratch in TypeScript using linked lists. Includes enqueue, dequeue, peek methods and real-world use cases."
keywords:
Expand Down
6 changes: 0 additions & 6 deletions src/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ const links: Array<{
url: string;
icon: string;
}> = [
{
labelKey: "links.run.label",
ariaKey: "links.run.aria",
url: "/run",
icon: "simple-icons:strava",
},
{
labelKey: "links.prepain.label",
ariaKey: "links.prepain.aria",
Expand Down
2 changes: 1 addition & 1 deletion src/layouts/BlogPost.astro
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ blogPostingSchema.speakable = {
};
---

<Layout title={title} description={metaDescription || description} keywords={keywords} image={heroImage}>
<Layout title={title} description={metaDescription || description} keywords={keywords} image={heroImage} ogType="article">
<main>
<article class="blog-post">
<header class="blog-header">
Expand Down
5 changes: 3 additions & 2 deletions src/layouts/Layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ interface Props {
description?: string;
keywords?: string[];
image?: string | ImageMetadata;
ogType?: 'website' | 'article';
}

const lang = getLangFromUrl(Astro.url);
const { title = SITE_TITLE[lang], description = SITE_DESCRIPTION[lang], keywords, image } = Astro.props;
const { title = SITE_TITLE[lang], description = SITE_DESCRIPTION[lang], keywords, image, ogType = 'website' } = Astro.props;
---

<!doctype html>
<html lang={lang}>
<head>
<BaseHead title={title} description={description} keywords={keywords} lang={lang} image={image} />
<BaseHead title={title} description={description} keywords={keywords} lang={lang} image={image} ogType={ogType} />
<!-- favicon -->
<link rel="icon" type="image/png" href="favicon.png" />

Expand Down