.
This commit is contained in:
@@ -1,60 +1,40 @@
|
||||
import { MetadataRoute } from 'next';
|
||||
import {
|
||||
fetchPublicPosts,
|
||||
} from '@/api/publicPosts';
|
||||
import { parseApiDate, SITE_URL } from '@/lib/site';
|
||||
|
||||
interface SitemapPost {
|
||||
slug: string;
|
||||
updatedAt?: string;
|
||||
createdAt?: string;
|
||||
}
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const revalidate = 300;
|
||||
|
||||
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
|
||||
const baseUrl = 'https://blog.wypark.me';
|
||||
// API 주소 환경변수 사용 (없으면 로컬)
|
||||
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080';
|
||||
|
||||
// 1. 고정된 정적 페이지들
|
||||
const generatedAt = new Date();
|
||||
const routes: MetadataRoute.Sitemap = [
|
||||
{
|
||||
url: baseUrl,
|
||||
lastModified: new Date(),
|
||||
url: SITE_URL,
|
||||
lastModified: generatedAt,
|
||||
changeFrequency: 'daily',
|
||||
priority: 1,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/archive`,
|
||||
lastModified: new Date(),
|
||||
url: `${SITE_URL}/archive`,
|
||||
lastModified: generatedAt,
|
||||
changeFrequency: 'daily',
|
||||
priority: 0.8,
|
||||
},
|
||||
];
|
||||
|
||||
try {
|
||||
// 2. API에서 게시글 목록 가져오기
|
||||
const response = await fetch(`${apiUrl}/api/posts?size=1000&sort=createdAt,desc`, {
|
||||
method: 'GET',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
next: { revalidate: 3600 }
|
||||
});
|
||||
const postsData = await fetchPublicPosts({ size: 1000, sort: 'createdAt,desc' });
|
||||
const posts = postsData?.content || [];
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch posts');
|
||||
}
|
||||
|
||||
const json = await response.json() as { data?: { content?: SitemapPost[] } };
|
||||
const posts = json.data?.content || [];
|
||||
|
||||
// 3. 게시글 데이터를 사이트맵 형식으로 변환
|
||||
const postRoutes = posts.map((post) => ({
|
||||
// 🛠️ 핵심 수정: slug를 encodeURIComponent로 감싸서 특수문자(&, 한글 등)를 안전하게 처리합니다.
|
||||
url: `${baseUrl}/posts/${encodeURIComponent(post.slug)}`,
|
||||
lastModified: new Date(post.updatedAt || post.createdAt || Date.now()),
|
||||
changeFrequency: 'weekly' as const,
|
||||
const postRoutes: MetadataRoute.Sitemap = posts
|
||||
.filter((post) => post.slug)
|
||||
.map((post) => ({
|
||||
url: `${SITE_URL}/posts/${encodeURIComponent(post.slug)}`,
|
||||
lastModified: parseApiDate(post.updatedAt || post.createdAt, generatedAt),
|
||||
changeFrequency: 'weekly',
|
||||
priority: 0.8,
|
||||
}));
|
||||
|
||||
return [...routes, ...postRoutes];
|
||||
|
||||
} catch (error) {
|
||||
console.error('Sitemap generation error:', error);
|
||||
return routes;
|
||||
}
|
||||
return [...routes, ...postRoutes];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user