Skip to content

Commit 2c3a281

Browse files
feat: enhance SEO with dynamic sitemap/robots generation and updated schema markup for data pages.
1 parent aa1dd40 commit 2c3a281

9 files changed

Lines changed: 387 additions & 181 deletions

File tree

‎public/sitemap.xml‎

Lines changed: 58 additions & 58 deletions
Large diffs are not rendered by default.

‎public/yourselftoscience.pdf‎

7 KB
Binary file not shown.

‎src/app/data-types/[slug]/page.js‎

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,41 @@ export default function DataTypeNodePage({ params }) {
5555

5656
// Generate the JSON-LD payload for the Semantic Web
5757
// This explicitly tells Wikidata that this page defines a Class/Term
58-
const jsonLd = {
59-
"@context": "https://schema.org/",
60-
"@type": "DefinedTerm",
61-
"@id": `https://yourselftoscience.org/data-types/${dataType.slug}`,
62-
"name": dataType.title,
63-
"description": dataType.description,
64-
"identifier": dataType.id,
65-
"inDefinedTermSet": "https://yourselftoscience.org/data-types"
66-
};
58+
const jsonLd = [
59+
{
60+
"@context": "https://schema.org/",
61+
"@type": "DefinedTerm",
62+
"@id": `https://yourselftoscience.org/data-types/${dataType.slug}`,
63+
"name": dataType.title,
64+
"description": dataType.description,
65+
"identifier": dataType.id,
66+
"inDefinedTermSet": "https://yourselftoscience.org/data-types"
67+
},
68+
{
69+
"@context": "https://schema.org",
70+
"@type": "BreadcrumbList",
71+
"itemListElement": [
72+
{
73+
"@type": "ListItem",
74+
"position": 1,
75+
"name": "Home",
76+
"item": "https://yourselftoscience.org/"
77+
},
78+
{
79+
"@type": "ListItem",
80+
"position": 2,
81+
"name": "Data Dictionary",
82+
"item": "https://yourselftoscience.org/data-types"
83+
},
84+
{
85+
"@type": "ListItem",
86+
"position": 3,
87+
"name": dataType.title,
88+
"item": `https://yourselftoscience.org/data-types/${dataType.slug}`
89+
}
90+
]
91+
}
92+
];
6793

6894
return (
6995
<main className="max-w-4xl mx-auto py-12 px-4 sm:px-6 lg:px-8">

‎src/app/data-types/page.js‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,31 @@ export default function DataTypesPage() {
1515
// Sort ontology alphabetically by title
1616
const sortedTypes = [...dataTypesOntology].sort((a, b) => a.title.localeCompare(b.title));
1717

18+
const jsonLd = {
19+
"@context": "https://schema.org",
20+
"@type": "BreadcrumbList",
21+
"itemListElement": [
22+
{
23+
"@type": "ListItem",
24+
"position": 1,
25+
"name": "Home",
26+
"item": "https://yourselftoscience.org/"
27+
},
28+
{
29+
"@type": "ListItem",
30+
"position": 2,
31+
"name": "Data Dictionary",
32+
"item": "https://yourselftoscience.org/data-types"
33+
}
34+
]
35+
};
36+
1837
return (
1938
<main className="max-w-4xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
39+
<script
40+
type="application/ld+json"
41+
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
42+
/>
2043
<div className="mb-10 text-center">
2144
<h1 className="text-4xl font-extrabold text-gray-900 sm:text-5xl flex items-center justify-center">
2245
<FaBook className="mr-4 text-blue-600" /> Data Dictionary

‎src/app/data/page.js‎

Lines changed: 77 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -36,64 +36,84 @@ export default function DataPage() {
3636
setTimeout(() => setCopiedUrl(null), 2500);
3737
};
3838

39-
const jsonLd = {
40-
"@context": "https://schema.org/",
41-
"@type": "Dataset",
42-
"name": "Yourself to Science Open Dataset",
43-
"description": "A curated, open-access catalog of services, platforms, and programs that allow individuals to securely contribute to scientific research with their biological and digital selves.",
44-
"url": "https://yourselftoscience.org/data",
45-
"sameAs": "https://yourselftoscience.org/resources.ttl#dataset",
46-
"identifier": [
47-
"https://yourselftoscience.org/resources.ttl#dataset",
48-
`https://doi.org/${permanentDoi}`
49-
],
50-
"keywords": [
51-
"open dataset",
52-
"CC0 dataset",
53-
"public domain data",
54-
"science data",
55-
"clinical trials data",
56-
"citizen science dataset",
57-
"JSON API",
58-
"CSV download",
59-
"linked data",
60-
"research opportunities"
61-
],
62-
"alternateName": [
63-
"Yourself to Science Catalogue",
64-
"Yourself to Science Database"
65-
],
66-
"creator": {
67-
"@type": "Organization",
68-
"name": "Yourself to Science",
69-
"url": "https://yourselftoscience.org",
70-
"contactPoint": {
71-
"@type": "ContactPoint",
72-
"contactType": "public engagement",
73-
"email": "hello@yourselftoscience.org"
74-
}
75-
},
76-
"license": "https://creativecommons.org/publicdomain/zero/1.0/",
77-
"isAccessibleForFree": true,
78-
"dateModified": lastUpdatedMeta.dateModified,
79-
"distribution": [
80-
{
81-
"@type": "DataDownload",
82-
"encodingFormat": "text/csv",
83-
"contentUrl": "https://yourselftoscience.org/resources.csv"
84-
},
85-
{
86-
"@type": "DataDownload",
87-
"encodingFormat": "application/json",
88-
"contentUrl": "https://yourselftoscience.org/resources.json"
39+
const jsonLd = [
40+
{
41+
"@context": "https://schema.org/",
42+
"@type": "Dataset",
43+
"name": "Yourself to Science Open Dataset",
44+
"description": "A curated, open-access catalog of services, platforms, and programs that allow individuals to securely contribute to scientific research with their biological and digital selves.",
45+
"url": "https://yourselftoscience.org/data",
46+
"sameAs": "https://yourselftoscience.org/resources.ttl#dataset",
47+
"identifier": [
48+
"https://yourselftoscience.org/resources.ttl#dataset",
49+
`https://doi.org/${permanentDoi}`
50+
],
51+
"keywords": [
52+
"open dataset",
53+
"CC0 dataset",
54+
"public domain data",
55+
"science data",
56+
"clinical trials data",
57+
"citizen science dataset",
58+
"JSON API",
59+
"CSV download",
60+
"linked data",
61+
"research opportunities"
62+
],
63+
"alternateName": [
64+
"Yourself to Science Catalogue",
65+
"Yourself to Science Database"
66+
],
67+
"creator": {
68+
"@type": "Organization",
69+
"name": "Yourself to Science",
70+
"url": "https://yourselftoscience.org",
71+
"contactPoint": {
72+
"@type": "ContactPoint",
73+
"contactType": "public engagement",
74+
"email": "hello@yourselftoscience.org"
75+
}
8976
},
90-
{
91-
"@type": "DataDownload",
92-
"encodingFormat": "text/turtle",
93-
"contentUrl": "https://yourselftoscience.org/resources.ttl"
94-
}
95-
]
96-
};
77+
"license": "https://creativecommons.org/publicdomain/zero/1.0/",
78+
"isAccessibleForFree": true,
79+
"dateModified": lastUpdatedMeta.dateModified,
80+
"distribution": [
81+
{
82+
"@type": "DataDownload",
83+
"encodingFormat": "text/csv",
84+
"contentUrl": "https://yourselftoscience.org/resources.csv"
85+
},
86+
{
87+
"@type": "DataDownload",
88+
"encodingFormat": "application/json",
89+
"contentUrl": "https://yourselftoscience.org/resources.json"
90+
},
91+
{
92+
"@type": "DataDownload",
93+
"encodingFormat": "text/turtle",
94+
"contentUrl": "https://yourselftoscience.org/resources.ttl"
95+
}
96+
]
97+
},
98+
{
99+
"@context": "https://schema.org",
100+
"@type": "BreadcrumbList",
101+
"itemListElement": [
102+
{
103+
"@type": "ListItem",
104+
"position": 1,
105+
"name": "Home",
106+
"item": "https://yourselftoscience.org/"
107+
},
108+
{
109+
"@type": "ListItem",
110+
"position": 2,
111+
"name": "Data Infrastructure",
112+
"item": "https://yourselftoscience.org/data"
113+
}
114+
]
115+
}
116+
];
97117

98118
return (
99119
<main className="flex-grow w-full max-w-screen-xl mx-auto px-4 py-12 md:py-16">

‎src/app/explore/page.js‎

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,31 @@ export default function ExplorePage() {
323323

324324
const displayedColumns = ALL_COLUMNS.filter(c => visibleCols.has(c.key));
325325

326+
const jsonLd = {
327+
"@context": "https://schema.org",
328+
"@type": "BreadcrumbList",
329+
"itemListElement": [
330+
{
331+
"@type": "ListItem",
332+
"position": 1,
333+
"name": "Home",
334+
"item": "https://yourselftoscience.org/"
335+
},
336+
{
337+
"@type": "ListItem",
338+
"position": 2,
339+
"name": "Data Explorer",
340+
"item": "https://yourselftoscience.org/explore"
341+
}
342+
]
343+
};
344+
326345
return (
327346
<main className="flex-grow w-full max-w-[1600px] mx-auto px-4 py-8 md:py-12">
347+
<script
348+
type="application/ld+json"
349+
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
350+
/>
328351
{/* Header */}
329352
<div className="mb-8">
330353
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-2">
@@ -452,7 +475,9 @@ export default function ExplorePage() {
452475
{displayedColumns.map(col => (
453476
<th
454477
key={col.key}
455-
className="px-4 py-3 font-semibold text-xs text-slate-500 uppercase tracking-wider cursor-pointer hover:bg-slate-100 select-none transition-colors whitespace-nowrap"
478+
className={`px-4 py-3 font-semibold text-xs text-slate-500 uppercase tracking-wider cursor-pointer hover:bg-slate-100 select-none transition-colors whitespace-nowrap ${
479+
col.key === 'title' ? 'sticky left-0 z-20 bg-slate-50/80 shadow-[2px_0_5px_-2px_rgba(0,0,0,0.1)]' : ''
480+
}`}
456481
style={{ minWidth: col.minWidth }}
457482
onClick={() => handleSort(col.key)}
458483
>
@@ -488,7 +513,12 @@ export default function ExplorePage() {
488513
className="hover:bg-blue-50/30 transition-colors group"
489514
>
490515
{displayedColumns.map(col => (
491-
<td key={col.key} className="px-4 py-3 align-top">
516+
<td
517+
key={col.key}
518+
className={`px-4 py-3 align-top ${
519+
col.key === 'title' ? 'sticky left-0 z-10 bg-white group-hover:bg-blue-50/30 transition-colors shadow-[2px_0_5px_-2px_rgba(0,0,0,0.1)]' : ''
520+
}`}
521+
>
492522
{col.key === 'title' ? (
493523
<div>
494524
<Link

0 commit comments

Comments
 (0)