Skip to content

Feature: JSON-LD 추가 #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import './globals.css';

import { Suspense } from 'react';

import { JsonLD } from '@/components';
import { Analytics } from '@/components/Analytics';
import { OverlayProvider } from '@/components/Overlay/OverlayProvider';
import METADATA from '@/constants/meta';
Expand All @@ -15,11 +16,12 @@ export const metadata: Metadata = METADATA;
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ko">
<body className="flex w-screen touch-none justify-center bg-slate-100">
<div className="w-full max-w-440 overflow-scroll bg-white text-primary">
<body className="flex justify-center w-screen touch-none bg-slate-100">
<div className="w-full overflow-scroll bg-white max-w-440 text-primary">
<Suspense>
<Analytics />
</Suspense>
<JsonLD />
<QueryProvider>
<RecoilProvider>
<OverlayProvider>{children}</OverlayProvider>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. JsonLD 컴포넌트를 가져오기 위해 새로운 import 문이 추가되었습니다. 이 코드 변경은 기능적인 면에서 안전합니다.

  2. RootLayout 함수 내에서 <JsonLD /> 컴포넌트가 Suspense 컴포넌트로 감싸여 있지 않습니다. 만약 JsonLD 컴포넌트가 데이터를 비동기적으로 로드한다면, Suspense로 감쌀 것을 고려해 볼 수 있습니다.

  3. 코드 리뷰에는 주로 더 많은 context나 페이지 전반의 처리 방식이 필요하지만, 해당 코드 조각 자체가 작아서 뚜렷한 문제점이 나타나지는 않습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Suspense는 주로 비동기 작업(데이터 패칭, 지연 로딩 컴포넌트)을 처리하기 위해 사용합니다. JSON-LD스크립트는 정적 메타 데이터로, 비동기 로딩이 필요하지 않습니다.

또한, Suspense로 감싸면 서버에서 렌더링을 하지 않기 때문에 내부 컴포넌트의 렌더링에 있어서 지연이 발생해 SEO에 부정적인 영향을 미칠 수 있습니다.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 코드 패치는 대부분 좋아 보입니다. 개선 제안은 다음과 같습니다:

  1. Suspense 구성 요소에서 Error Boundary가 없으므로 코드에서 발생할 수 있는 오류를 처리하는 방법을 고려할 필요가 있습니다.
  2. JsonLD 컴포넌트의 위치는 Analytics 컴포넌트 다음에 배치되어 있지만, JsonLD 컴포넌트의 의존성 및 논리적 순서를 고려하여 올바른 위치에 배치되었는지 확인해야 합니다.

Expand Down
15 changes: 15 additions & 0 deletions src/components/JsonLD/JsonLD.tsx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

layout.tsx에서만 사용되는 컴포넌트인만큼,, 따로 빼서 컴포넌트 폴더를 늘리는 것 보다 한 파일 내에서 선언하면 좋을 것 같습니다..!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

layout.tsx파일 하나에 전부 넣으면 코드의 가독성을 해치지 않을까 해서 분리를했습니다. 예들 들어 현재 layout.tsx에 있는 Analytics처럼요. QueryProvider와 RecoilProvider는 RCC라 분리가 불가피한 컾모넌트라고 생각합니다.

정리하면, 가독성을 위해 컴포넌트는 분리하는 것이 좋다고 생각하며 저희가 최근에 구두로 정한 컴포넌트 구조 컨벤션처럼, layout.tsx에서 사용하는 컴포넌트는 layout.tsx와 동일한 depth에 작성하는 방안을 제안합니다.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제안해주신 방안으로 진행하면 좋을 것 같습니다!!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Script from 'next/script';

import { JSON_LD } from '@/constants';

export default function JsonLD() {
return (
<Script
id="faq-schema"
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify(JSON_LD),
}}
/>
);
}
1 change: 1 addition & 0 deletions src/components/JsonLD/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as JsonLD } from './JsonLD';
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './JsonLD';
1 change: 1 addition & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './meta';
36 changes: 36 additions & 0 deletions src/constants/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,39 @@ const METADATA: Metadata = {
};

export default METADATA;

export const JSON_LD = {
'@context': 'https://schema.org',
'@type': 'WebSite',
name: 'PosePicker | 포즈피커',
description: '포토부스에서 고민하는 당신을 위한 포즈 추천 서비스',
keywords: 'pose, photo booth, recommendation, 포즈, 포토부스, 추천',
url: 'https://www.posepicker.site',
image: 'https://www.posepicker.site/meta/og_main.png',
author: {
'@type': 'Organization',
name: 'PosePicker',
},
datePublished: '2024-08-08T00:00:00+09:00',
dateModified: '2024-08-08T00:00:00+09:00',
publisher: {
'@type': 'Organization',
name: 'PosePicker',
logo: {
'@type': 'ImageObject',
url: 'https://www.posepicker.site/pwa-icons/apple.png',
},
},
headline: '포즈가 고민될 땐? 포즈피커!',
mainEntityOfPage: {
'@type': 'WebPage',
'@id': 'https://www.posepicker.site',
},
offers: {
'@type': 'Offer',
price: '0',
priceCurrency: 'KRW',
availability: 'https://schema.org/InStock',
},
thumbnailUrl: 'https://www.posepicker.site/meta/og_main.png',
};