Next.js
Beginner
1 min read
Icons, Manifest, and Structured Data
Example
// app/manifest.ts
import type { MetadataRoute } from 'next';
export default function manifest(): MetadataRoute.Manifest {
return {
name: 'Acme App',
short_name: 'Acme',
description: 'Build faster with Acme',
start_url: '/',
display: 'standalone',
background_color: '#ffffff',
theme_color: '#0f172a',
icons: [
{ src: '/icon-192.png', sizes: '192x192', type: 'image/png' },
{ src: '/icon-512.png', sizes: '512x512', type: 'image/png' },
],
};
}
// app/blog/[slug]/page.tsx — JSON-LD structured data
interface Post {
slug: string;
title: string;
excerpt: string;
author: string;
publishedAt: string;
coverImageUrl: string;
}
function ArticleJsonLd({ post }: { post: Post }) {
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: post.title,
description: post.excerpt,
image: post.coverImageUrl,
author: { '@type': 'Person', name: post.author },
datePublished: post.publishedAt,
publisher: {
'@type': 'Organization',
name: 'Acme',
logo: { '@type': 'ImageObject', url: 'https://acme.com/logo.png' },
},
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
);
}
export default async function BlogPostPage({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug);
return (
<>
<ArticleJsonLd post={post} />
<article>
<h1>{post.title}</h1>
</article>
</>
);
}