chore: update package manager and enhance icon metadata

- Updated package manager version to pnpm@10.11.0 in package.json.
- Added robots metadata for SEO in page.tsx.
- Changed Open Graph type from "article" to "website" and added siteName and images.
- Included canonical URL in alternates for better indexing.
- Added structured data for icons in the IconDetails component with priority loading for images.
This commit is contained in:
Thomas Camlong 2025-05-19 15:13:16 +02:00
parent ce0e7a5c31
commit 659384a6d4
No known key found for this signature in database
GPG Key ID: A678F374F428457B
3 changed files with 47 additions and 10 deletions

View File

@ -77,7 +77,7 @@
"typescript": "^5.8.3", "typescript": "^5.8.3",
"wrangler": "^4.12.0" "wrangler": "^4.12.0"
}, },
"packageManager": "pnpm@10.8.0", "packageManager": "pnpm@10.11.0",
"pnpm": { "pnpm": {
"onlyBuiltDependencies": [ "onlyBuiltDependencies": [
"@biomejs/biome", "@biomejs/biome",

View File

@ -1,9 +1,7 @@
import { IconDetails } from "@/components/icon-details" import { IconDetails } from "@/components/icon-details"
import { BASE_URL, WEB_URL } from "@/constants" import { BASE_URL, WEB_URL } from "@/constants"
import { getAllIcons, getAuthorData } from "@/lib/api" import { getAllIcons, getAuthorData } from "@/lib/api"
import { formatIconName } from "@/lib/utils"
import type { Metadata, ResolvingMetadata } from "next" import type { Metadata, ResolvingMetadata } from "next"
import { default as dynamicImport } from "next/dynamic"
import { notFound } from "next/navigation" import { notFound } from "next/navigation"
export const dynamicParams = false export const dynamicParams = false
@ -67,17 +65,32 @@ export async function generateMetadata({ params, searchParams }: Props, parent:
icons: { icons: {
icon: `${BASE_URL}/webp/${icon}.webp`, icon: `${BASE_URL}/webp/${icon}.webp`,
}, },
robots: {
index: true,
follow: true,
nocache: false,
googleBot: {
index: true,
follow: true,
noimageindex: false,
"max-video-preview": -1,
"max-image-preview": "large",
},
},
abstract: `Download the ${formattedIconName} icon in SVG, PNG, and WEBP formats for FREE. Part of a collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`, abstract: `Download the ${formattedIconName} icon in SVG, PNG, and WEBP formats for FREE. Part of a collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`,
openGraph: { openGraph: {
title: `${formattedIconName} Icon | Dashboard Icons`, title: `${formattedIconName} Icon | Dashboard Icons`,
description: `Download the ${formattedIconName} icon in SVG, PNG, and WEBP formats for FREE. Part of a collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`, description: `Download the ${formattedIconName} icon in SVG, PNG, and WEBP formats for FREE. Part of a collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`,
type: "article", type: "website",
url: pageUrl, url: pageUrl,
authors: [authorName], siteName: "Dashboard Icons",
publishedTime: updateDate.toISOString(), images: [{
modifiedTime: updateDate.toISOString(), url: `${BASE_URL}/webp/${icon}.webp`,
section: "Icons", width: 512,
tags: [formattedIconName, "dashboard icon", "service icon", "application icon", "tool icon", "web dashboard", "app directory"], height: 512,
alt: `${formattedIconName} icon`,
}]
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -85,6 +98,7 @@ export async function generateMetadata({ params, searchParams }: Props, parent:
description: `Download the ${formattedIconName} icon in SVG, PNG, and WEBP formats for FREE. Part of a collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`, description: `Download the ${formattedIconName} icon in SVG, PNG, and WEBP formats for FREE. Part of a collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`,
}, },
alternates: { alternates: {
canonical: `${WEB_URL}/icons/${icon}`,
media: { media: {
png: `${BASE_URL}/png/${icon}.png`, png: `${BASE_URL}/png/${icon}.png`,
svg: `${BASE_URL}/svg/${icon}.svg`, svg: `${BASE_URL}/svg/${icon}.svg`,
@ -105,5 +119,26 @@ export default async function IconPage({ params }: { params: Promise<{ icon: str
const authorData = await getAuthorData(originalIconData.update.author.id) const authorData = await getAuthorData(originalIconData.update.author.id)
return <IconDetails icon={icon} iconData={originalIconData} authorData={authorData} allIcons={iconsData} /> return (
<>
<script
type="application/ld+json"
// biome-ignore lint/security/noDangerouslySetInnerHtml: Needs to be done
dangerouslySetInnerHTML={{
__html: JSON.stringify({
"@context": "https://schema.org",
"@type": "ImageObject",
contentUrl: `${BASE_URL}/png/${icon}.png`,
license: "https://creativecommons.org/licenses/by/4.0/",
acquireLicensePage: `${WEB_URL}/license`,
creator: {
"@type": "Person",
name: authorData.name || authorData.login,
},
}),
}}
/>
<IconDetails icon={icon} iconData={originalIconData} authorData={authorData} allIcons={iconsData} />
</>
)
} }

View File

@ -193,6 +193,7 @@ export function IconDetails({ icon, iconData, authorData, allIcons }: IconDetail
alt={`${iconName} in ${format} format${theme ? ` (${theme} theme)` : ""}`} alt={`${iconName} in ${format} format${theme ? ` (${theme} theme)` : ""}`}
fill fill
loading="eager" loading="eager"
priority
className="object-contain p-4" className="object-contain p-4"
/> />
</motion.div> </motion.div>
@ -276,6 +277,7 @@ export function IconDetails({ icon, iconData, authorData, allIcons }: IconDetail
<div className="relative w-32 h-32 rounded-xl overflow-hidden border flex items-center justify-center p-3"> <div className="relative w-32 h-32 rounded-xl overflow-hidden border flex items-center justify-center p-3">
<Image <Image
src={`${BASE_URL}/${iconData.base}/${icon}.${iconData.base}`} src={`${BASE_URL}/${iconData.base}/${icon}.${iconData.base}`}
priority
width={96} width={96}
height={96} height={96}
placeholder="empty" placeholder="empty"