Skip to content

Commit

Permalink
[#349] 메타 데이터 추가 (#617)
Browse files Browse the repository at this point in the history
* feat: 오픈그래프 이미지 추가

* feat: 메타데이터 title, description

* feat: 오픈그래프 이미지와 크기 수정

* fix: 오픈그래프 이미지 용량 축소

* fix: opengraph-image.tsx 파일 수정

* fix: Image Generator 제거

* feat: 오픈그래프 이미지 업데이트

* feat: RootLayout에 메타데이터 추가

* feat: Sitemap 작성

- 북카이브, 도서 검색, 독서 모임, 내 프로필
- 비회원 북카이브에 노출되는 책장 및 도서
- 전체 독서 모임

* feat: robots 작성

* fix: 오픈그래프 이미지 업데이트

* feat: site-verification 추가 (구글, 네이버)

* refactor: url주소 매직스트링을 환경변수로 교체

* refactor: sitemap을 route별로 분리

* chore: 불필요한 util 파일 삭제

* chore: 코드 리뷰 반영

* refactor: book sitemap 병합 및 route 변경

* refactor: route 위치 통일성 부여
  • Loading branch information
hanyugeon authored and gxxrxn committed Jun 17, 2024
1 parent 0425223 commit 209ba3e
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 1 deletion.
47 changes: 47 additions & 0 deletions src/app/book/sitemap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { MetadataRoute } from 'next';
import type { APIRecommendedBookshelf } from '@/types/bookshelf';
import type { APIBook } from '@/types/book';

const options = {
headers: {
'Content-Type': 'application/json',
},
next: { revalidate: 60 * 60 * 24 },
};

export async function booksSitemap() {
try {
const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/api/suggestions/bookshelves/default`,
options
);

if (!res.ok) {
return Promise.reject();
}

const data: APIRecommendedBookshelf = await res.json();

const books = new Set<APIBook['bookId']>();

data.bookshelfResponses.forEach(bookshelf =>
bookshelf.books.forEach(book => books.add(book.bookId))
);

const filteredBooks = Array.from(books);

return filteredBooks;
} catch {
return [];
}
}

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const booksId = await booksSitemap();
const sitemap = ['search', ...booksId];

return sitemap.map(value => ({
url: `${process.env.NEXT_PUBLIC_HOST}/book/${value}`,
lastModified: new Date(),
}));
}
40 changes: 40 additions & 0 deletions src/app/bookshelf/sitemap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { MetadataRoute } from 'next';
import type { APIRecommendedBookshelf } from '@/types/bookshelf';

const options = {
headers: {
'Content-Type': 'application/json',
},
next: { revalidate: 60 * 60 * 24 },
};

export async function bookshelvesSitemap() {
try {
const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/api/suggestions/bookshelves/default`,
options
);

if (!res.ok) {
return Promise.reject();
}

const data: APIRecommendedBookshelf = await res.json();
const bookshelves = data.bookshelfResponses.map(({ bookshelfId }) => ({
bookshelfId,
}));

return bookshelves;
} catch {
return [];
}
}

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const bookshelves = await bookshelvesSitemap();

return bookshelves.map(({ bookshelfId }) => ({
url: `${process.env.NEXT_PUBLIC_HOST}/bookshelf/${bookshelfId}`,
lastModified: new Date(),
}));
}
38 changes: 38 additions & 0 deletions src/app/group/sitemap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { MetadataRoute } from 'next';
import type { APIGroupPagination } from '@/types/group';

const options = {
headers: {
'Content-Type': 'application/json',
},
next: { revalidate: 60 * 60 * 24 },
};

export const bookGroupSitemap = async () => {
try {
const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/api/book-groups?pageSize=100`,
options
);

if (!res.ok) {
return Promise.reject();
}

const data: APIGroupPagination = await res.json();
const bookGroups = data.bookGroups.map(group => group.bookGroupId);

return bookGroups;
} catch {
return [];
}
};

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const bookGroups = await bookGroupSitemap();

return bookGroups.map(bookGroupId => ({
url: `${process.env.NEXT_HOST}/group/${bookGroupId}`,
lastModified: new Date(),
}));
}
30 changes: 29 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,47 @@
import { Metadata } from 'next';

import ContextProvider from '@/components/ContextProvider';
import AuthFailedErrorBoundary from '@/components/AuthFailedErrorBoundary';
import Layout from '@/v1/layout/Layout';

import { LineSeedKR } from '@/styles/font';
import '@/styles/global.css';

export const metadata: Metadata = {
metadataBase: new URL(`${process.env.NEXT_HOST}`),
title: {
template: '%s | 다독다독',
default: '다독다독',
},
description: '책에 대한 인사이트를 공유하고 소통하는 독서 소셜 플랫폼',
keywords: [
'다독다독',
'dadok',
'dadokdadok',
'책장',
'책추천',
'도서검색',
'독서모임',
'책',
'독서',
],
verification: {
google: '72kN3MWyQHuvSb8V67dVkfPUPMrw102Tm6BsvTvfKmg',
other: {
'naver-site-verification': '9046af5eda448309a92e2e923a45cb874df986a0',
},
},
};

const RootLayout = ({ children }: { children: React.ReactNode }) => {
return (
<html lang="ko">
<head>
<title>다독다독</title>
<meta
content="width=device-width, initial-scale=1, maximum-scale=1"
name="viewport"
/>
<meta charSet="UTF-8" />
<link rel="icon" href="/favicon.ico" />
</head>
{/* @todo Chakra 제거시 app-layout 프로퍼티 제거. */}
Expand Down
Binary file added src/app/opengraph-image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions src/app/robots.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { MetadataRoute } from 'next';

export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: '/',
},
sitemap: `${process.env.NEXT_HOST}/sitemap.xml`,
host: `${process.env.NEXT_HOST}`,
};
}
25 changes: 25 additions & 0 deletions src/app/sitemap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { MetadataRoute } from 'next';

import { default as bookSitemap } from './book/sitemap';
import { default as bookshelfSitemap } from './bookshelf/sitemap';
import { default as bookGroupSitemap } from './group/sitemap';

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
return [
{
url: `${process.env.NEXT_HOST}/bookarchive`,
lastModified: new Date(),
},
{
url: `${process.env.NEXT_HOST}/group`,
lastModified: new Date(),
},
{
url: `${process.env.NEXT_HOST}/profile/me`,
lastModified: new Date(),
},
...(await bookSitemap()),
...(await bookshelfSitemap()),
...(await bookGroupSitemap()),
];
}

0 comments on commit 209ba3e

Please sign in to comment.