Skip to content

Commit 7d458c0

Browse files
committed
SEO improvmenets
1 parent 18373cb commit 7d458c0

9 files changed

Lines changed: 103 additions & 9 deletions

File tree

src/app/about/page.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import { Content } from '@/lib/types/Content';
44
import React, { use } from 'react';
55

66
export const metadata = {
7-
title: 'Aaron Static - About'
7+
title: 'Aaron Static - About',
8+
description: 'About Aaron Static — Australian music artist and app developer. Biography, background, and influences behind his Ambient, Liquid Drum & Bass, Organic House, and Future Garage productions.',
9+
alternates: {
10+
canonical: '/about',
11+
},
812
}
913

1014
export default function About() {
@@ -14,6 +18,7 @@ export default function About() {
1418
let photoAlign = "float-end";
1519
return (
1620
<main className="">
21+
<h1 className="text-center p-2 mt-4 display-6">Aaron Static</h1>
1722
<div className="row justify-content-center">
1823
<div className="col-lg-7 col-md-8 col-12">
1924
{bio && bio.paragraphs.map((paragraph: string, i: number): React.ReactNode => {

src/app/contact/page.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import React from 'react';
22
import ContactForm from './ContactForm';
33

44
export const metadata = {
5-
title: 'Aaron Static - Contact'
5+
title: 'Aaron Static - Contact',
6+
description: 'Get in touch with Aaron Static for bookings, collaborations, licensing, and inquiries.',
7+
alternates: {
8+
canonical: '/contact',
9+
},
610
}
711

812
export default function Contact() {

src/app/layout.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ export const metadata = {
1414
icons: {
1515
icon: '/img/icon.png'
1616
},
17-
metadataBase: new URL('http://aaronstatic.com'),
17+
metadataBase: new URL('https://aaronstatic.com'),
18+
alternates: {
19+
canonical: '/',
20+
},
1821
keywords: ['music', 'artist', 'app developer', 'ambient', 'liquid', 'drum & bass', 'organic house', 'house', 'future garage', 'code'],
1922
openGraph: {
2023
title: "Aaron Static",

src/app/mixes/page.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import Mix from '@/lib/types/Mix';
55
import { use } from 'react';
66

77
export const metadata = {
8-
title: 'Aaron Static - Mixes'
8+
title: 'Aaron Static - Mixes',
9+
description: 'DJ mixes and sets by Aaron Static. Liquid Drum & Bass, Organic House, Future Garage, and Ambient mixes streamable online.',
10+
alternates: {
11+
canonical: '/mixes',
12+
},
913
}
1014

1115
export default function Mixes() {

src/app/music/[name]/page.tsx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { notFound } from 'next/navigation';
22
import Link from 'next/link';
33
import { getReleaseByName } from '@/lib/mongodb';
44
import { Review } from '@/lib/types/Release';
5+
import { releaseSlug } from '@/lib/slug';
56

67
// Helper function to convert milliseconds to minutes:seconds format
78
function msToMinutesSeconds(ms: number): string {
@@ -72,6 +73,9 @@ export async function generateMetadata({ params }: { params: tParams }) {
7273
description: release.description?.[0] || 'Music by Aaron Static',
7374
images: release.images?.[0]?.url ? [{ url: release.images[0].url }] : [],
7475
},
76+
alternates: {
77+
canonical: `/music/${releaseSlug(release.name)}`,
78+
},
7579
};
7680
}
7781

@@ -132,8 +136,49 @@ export default async function Release({ params }: { params: tParams }) {
132136

133137
const externalUrls = release.external_urls || {};
134138

139+
const canonicalUrl = `https://aaronstatic.com/music/${releaseSlug(release.name)}`;
140+
141+
const artistsList = release.artists && Array.isArray(release.artists) && release.artists.length > 0
142+
? release.artists.map((a: any) => ({
143+
"@type": "MusicGroup",
144+
name: a.name,
145+
...(a.external_urls?.spotify ? { url: a.external_urls.spotify } : {})
146+
}))
147+
: [{ "@type": "MusicGroup", name: "Aaron Static", url: "https://aaronstatic.com" }];
148+
149+
const tracksList = release.tracks && Array.isArray(release.tracks)
150+
? release.tracks.map((t: any, i: number) => ({
151+
"@type": "MusicRecording",
152+
name: t.name,
153+
...(typeof t.duration_ms === 'number' && t.duration_ms > 0 ? { duration: `PT${Math.floor(t.duration_ms / 60000)}M${Math.floor((t.duration_ms % 60000) / 1000)}S` } : {}),
154+
position: i + 1,
155+
byArtist: t.artists && Array.isArray(t.artists) && t.artists.length > 0
156+
? t.artists.map((a: any) => ({ "@type": "MusicGroup", name: a.name }))
157+
: artistsList,
158+
}))
159+
: undefined;
160+
161+
const schema: Record<string, any> = {
162+
"@context": "https://schema.org",
163+
"@type": "MusicAlbum",
164+
name: release.name,
165+
url: canonicalUrl,
166+
byArtist: artistsList.length === 1 ? artistsList[0] : artistsList,
167+
...(release.images?.[0]?.url ? { image: release.images[0].url } : {}),
168+
...(release.release_date ? { datePublished: release.release_date } : {}),
169+
...(release.label ? { recordLabel: { "@type": "Organization", name: release.label } } : {}),
170+
...(release.genres && release.genres.length > 0 ? { genre: release.genres } : {}),
171+
...(release.description && release.description.length > 0 ? { description: release.description.join(' ') } : {}),
172+
...(typeof release.tracks?.length === 'number' ? { numTracks: release.tracks.length } : {}),
173+
...(tracksList ? { track: tracksList } : {}),
174+
};
175+
135176
return (
136177
<main className="">
178+
<script
179+
type="application/ld+json"
180+
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
181+
/>
137182
<h1 className="text-center display-6">{releaseTitle}</h1>
138183
<div className="row justify-content-center">
139184
<div className="col-lg-3 col-md-7 col-12">

src/app/music/page.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import Release from '@/lib/types/Release';
55
import { use } from 'react';
66

77
export const metadata = {
8-
title: 'Aaron Static - Music'
8+
title: 'Aaron Static - Music',
9+
description: 'Discography of Aaron Static — albums, singles, and appearances across Ambient, Liquid Drum & Bass, Organic House, and Future Garage.',
10+
alternates: {
11+
canonical: '/music',
12+
},
913
}
1014

1115
export default function Music() {

src/app/page.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,38 @@ export default function Home() {
1010
const mixes: Mix[] = use(getMixes(6));
1111
return (
1212
<main className="">
13+
<script
14+
type="application/ld+json"
15+
dangerouslySetInnerHTML={{ __html: JSON.stringify({
16+
"@context": "https://schema.org",
17+
"@type": ["Person", "MusicGroup"],
18+
"name": "Aaron Static",
19+
"url": "https://aaronstatic.com",
20+
"image": "https://aaronstatic.com/img/social-preview.jpg",
21+
"nationality": "Australian",
22+
"jobTitle": "Music Artist and App Developer",
23+
"description": "Australian-based music artist and app developer producing Ambient, Liquid Drum & Bass, Organic House, Future Garage, and code to help people write music.",
24+
"genre": ["Ambient", "Liquid Drum & Bass", "Organic House", "Future Garage"],
25+
"sameAs": [
26+
"https://open.spotify.com/artist/0Nsz79ZcE8E4i3XZhCzZ1l",
27+
"https://instagram.com/aaronstatic",
28+
"https://facebook.com/aaronstatic",
29+
"https://twitter.com/aaronstatic",
30+
"https://soundcloud.com/aaronstatic",
31+
"https://youtube.com/aaronstatic",
32+
"https://github.com/aaronstatic",
33+
"https://patreon.com/aaronstatic"
34+
]
35+
}) }}
36+
/>
37+
<h1 className="visually-hidden">Aaron Static</h1>
1338
<div className="row justify-content-center">
1439
<div className="col-lg-7 col-md-8 col-12">
1540
<img className="img-fluid" src="/img/aaronstatic_photo_home.jpg" alt="Aaron Static" />
1641
</div>
1742
</div>
1843
<div className="row justify-content-center mt-3">
19-
<h1 className="text-center p-2 display-6">Latest Releases</h1>
44+
<h2 className="text-center p-2 display-6">Latest Releases</h2>
2045
<div className="row gy-2 gx-2 d-flex justify-content-center">
2146
{releases.map((release) => (
2247
<div className="col-lg-2 col-md-3 col-6" key={release.id}>
@@ -31,7 +56,7 @@ export default function Home() {
3156
</div>
3257
</div>
3358
<div className="row justify-content-center mt-3">
34-
<h1 className="text-center p-2 display-6">Latest Mixes</h1>
59+
<h2 className="text-center p-2 display-6">Latest Mixes</h2>
3560
<div className="row gy-2 gx-2 d-flex justify-content-center">
3661
{mixes.map((mix) => (
3762
<div key={mix.key} className="col-lg-2 col-md-3 col-6">

src/app/projects/page.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import Project from '@/lib/types/Project';
55
import { use } from 'react';
66

77
export const metadata = {
8-
title: 'Aaron Static - Projects'
8+
title: 'Aaron Static - Projects',
9+
description: 'Software and music-tech projects by Aaron Static — VCV Rack modules, web apps, and tools for musicians.',
10+
alternates: {
11+
canonical: '/projects',
12+
},
913
}
1014

1115
export default function Projects() {

tsconfig.tsbuildinfo

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)