Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 12 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Metadata } from 'next';
import { Geist, Geist_Mono } from 'next/font/google';
import '@/styles/globals.css';
import ClientHeader from '@/components/ClientHeader';
import GoogleAnalytics from '@/components/GoogleAnalytics';

const geistSans = Geist({
variable: '--font-geist-sans',
Expand All @@ -25,9 +26,20 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<head>
{/* 구글 애드센스 스크립트 */}
<script
async
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3712642250263014"
crossOrigin="anonymous"
></script>
</head>
Comment on lines +29 to +36
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

AdSense 클라이언트 ID도 환경 변수로 관리해야 합니다.

현재 AdSense 클라이언트 ID가 하드코딩되어 있는데, GoogleAnalytics 컴포넌트와 동일하게 환경 변수로 관리하는 것이 일관성 있고 안전합니다. 또한 Next.js 13+ App Router에서는 next/script의 Script 컴포넌트를 사용하는 것이 권장됩니다.

다음과 같이 별도의 GoogleAdsense 컴포넌트를 생성하여 일관성을 유지할 수 있습니다:

src/components/GoogleAdsense.tsx 파일을 새로 생성:

'use client';

import Script from 'next/script';

const GoogleAdsense = () => {
  const adsenseId = process.env.NEXT_PUBLIC_ADSENSE_ID;

  if (!adsenseId) {
    return null;
  }

  return (
    <Script
      async
      src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${adsenseId}`}
      crossOrigin="anonymous"
      strategy="afterInteractive"
    />
  );
};

export default GoogleAdsense;

src/app/layout.tsx에 적용:

 import ClientHeader from '@/components/ClientHeader';
 import GoogleAnalytics from '@/components/GoogleAnalytics';
+import GoogleAdsense from '@/components/GoogleAdsense';

...

 return (
   <html lang="en">
-    <head>
-      {/* 구글 애드센스 스크립트 */}
-      <script
-        async
-        src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3712642250263014"
-        crossOrigin="anonymous"
-      ></script>
-    </head>
     <body
       className={`${geistSans.variable} ${geistMono.variable} antialiased bg-gray-50 text-gray-900`}
     >
+      {/* 구글 애드센스 컴포넌트 */}
+      <GoogleAdsense />
+
       {/* 구글 애널리틱스 컴포넌트 */}
       <GoogleAnalytics />

그런 다음 .env 파일에 다음을 추가:

NEXT_PUBLIC_ADSENSE_ID=ca-pub-3712642250263014
🤖 Prompt for AI Agents
In src/app/layout.tsx around lines 29 to 36, the AdSense client ID is hardcoded
and a plain script tag is used; create a new client component
src/components/GoogleAdsense.tsx that uses 'use client' and next/script's Script
component to load the ads script with strategy="afterInteractive", read the
client ID from process.env.NEXT_PUBLIC_ADSENSE_ID and return null if it's
missing, then remove the hardcoded <script> from layout.tsx and import/include
the new GoogleAdsense component there; also add
NEXT_PUBLIC_ADSENSE_ID=ca-pub-3712642250263014 to the .env file (or set the
appropriate env value).

<body
className={`${geistSans.variable} ${geistMono.variable} antialiased bg-gray-50 text-gray-900`}
>
{/* 구글 애널리틱스 컴포넌트 */}
<GoogleAnalytics />

{/* 전역 헤더 */}
<ClientHeader />

Expand Down
37 changes: 37 additions & 0 deletions src/components/GoogleAnalytics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use client'; // 클라이언트 컴포넌트임을 명시합니다.

import Script from 'next/script';

const GoogleAnalytics = () => {
const gaId = process.env.NEXT_PUBLIC_GA_ID;

// 환경 변수가 설정되지 않았다면 아무것도 렌더링하지 않습니다.
if (!gaId) {
return null;
}

return (
<>
{/* 외부 gtag.js 스크립트를 로드합니다. */}
<Script
strategy="afterInteractive" // 페이지가 상호작용 가능해진 후에 스크립트를 로드합니다.
src={`https://www.googletagmanager.com/gtag/js?id=${gaId}`}
/>
{/* gtag 초기화 및 설정 스크립트를 삽입합니다. */}
<Script
id="gtag-init"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${gaId}');
`,
}}
/>
</>
);
};

export default GoogleAnalytics;