From efe77d14e92bb1073973bb375944fce266f264ce Mon Sep 17 00:00:00 2001 From: Eugene Kim Date: Sat, 1 Jul 2023 01:52:40 +0900 Subject: [PATCH 1/3] =?UTF-8?q?docs:=20analytics.mdx=20=EB=B2=88=EC=97=AD?= =?UTF-8?q?=20=EC=B4=88=EC=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../05-optimizing/07-analytics.mdx | 114 ++++++++---------- 1 file changed, 51 insertions(+), 63 deletions(-) diff --git a/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx b/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx index c15323a8c..15ee89ce1 100644 --- a/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx +++ b/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx @@ -1,20 +1,19 @@ --- title: Analytics -description: Measure and track page performance using Next.js Speed Insights +description: Next.js Speed Insights를 사용하여 페이지의 성능을 측정하고 추적할 수 있습니다. --- -[Next.js Speed Insights](https://nextjs.org/analytics) allows you to analyze and measure the performance of -pages using different metrics. +[Next.js Speed Insights](https://nextjs.org/analytics)를 사용하면 다양한 지표를 사용하여 페이지의 성능을 측정하고 분석할 수 있습니다. -You can start collecting your [Real Experience Score](https://vercel.com/docs/concepts/speed-insights#core-web-vitals-explained?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) with zero-configuration on [Vercel deployments](https://vercel.com/docs/concepts/speed-insights?utm_source=next-site&utm_medium=docs&utm_campaign=next-website). +[Vercel deployments](https://vercel.com/docs/concepts/speed-insights?utm_source=next-site&utm_medium=docs&utm_campaign=next-website)에서는 별다른 설정 없이 [Real Experience Score(RES)](https://vercel.com/docs/concepts/speed-insights#core-web-vitals-explained?utm_source=next-site&utm_medium=docs&utm_campaign=next-website)에 대한 정보를 수집할 수 있습니다. -The rest of this documentation describes the built-in relayer Next.js Speed Insights uses. +문서의 이후 내용은 Next.js의 Speed Insights에 기본적인 기능으로 사용하고 있는 `relayer`에 대하여 설명합니다. -## Build Your Own +## 직접 구현해보기 -First, you will need to create a [custom App](/docs/pages/building-your-application/routing/custom-app) component and define a `reportWebVitals` function: +먼저, [커스텀 앱](/docs/pages/building-your-application/routing/custom-app) 컴포넌트를 생성하고, `reportWebVitals` 함수를 정의합니다. ```jsx filename="pages/_app.js" export function reportWebVitals(metric) { @@ -27,19 +26,17 @@ function MyApp({ Component, pageProps }) { export default MyApp ``` +함수는 페이지에 존재하는 모든 매트릭의 최종적인 값에 대한 계산이 완료되었을 때 실행됩니다. 이에 대한 결과 일부를 콘솔에 기록하거나 특정 엔드포인트로 전송하는 데 사용할 수 있습니다. -This function is fired when the final values for any of the metrics have finished calculating on -the page. You can use to log any of the results to the console or send to a particular endpoint. +`metric` 객체는 다음과 같이 여러 속성으로 구성됩니다. -The `metric` object returned to the function consists of a number of properties: +- `id`: 현재 로드된 페이지의 맥락 속에서 사용하는 매트릭의 고유 식별자입니다. +- `name`: 매트릭의 이름 +- `startTime`: 성능 엔트리에서 첫 번째로 기록된 타임스탬프입니다. 이는 [밀리초](https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp) 단위입니다. (해당되는 경우) +- `value`: 성능 엔트리의 값 또는 지속 시간입니다. 이는 [밀리초](https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp) 단위입니다. +- `label`: 매트릭의 종류 (`web-vital` 또는 `custom`) -- `id`: Unique identifier for the metric in the context of the current page load -- `name`: Metric name -- `startTime`: First recorded timestamp of the performance entry in [milliseconds](https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp) (if applicable) -- `value`: Value, or duration in [milliseconds](https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp), of the performance entry -- `label`: Type of metric (`web-vital` or `custom`) - -There are two types of metrics that are tracked: +성능 추적에 사용할 수 있는 두 가지 유형의 매트릭입니다. - Web Vitals - Custom metrics @@ -48,50 +45,48 @@ There are two types of metrics that are tracked: ## Web Vitals -[Web Vitals](https://web.dev/vitals/) are a set of useful metrics that aim to capture the user -experience of a web page. The following web vitals are all included: +[Web Vitals](https://web.dev/vitals/)은 웹 페이지에 대한 사용자 경험(UX)을 측정하기 위하여 구성된 유용한 매트릭의 집합입니다. 다음과 같은 web vitals가 모두 포함됩니다. - [Time to First Byte](https://developer.mozilla.org/en-US/docs/Glossary/Time_to_first_byte) (TTFB) - [First Contentful Paint](https://developer.mozilla.org/en-US/docs/Glossary/First_contentful_paint) (FCP) - [Largest Contentful Paint](https://web.dev/lcp/) (LCP) - [First Input Delay](https://web.dev/fid/) (FID) - [Cumulative Layout Shift](https://web.dev/cls/) (CLS) -- [Interaction to Next Paint](https://web.dev/inp/) (INP) _(experimental)_ +- [Interaction to Next Paint](https://web.dev/inp/) (INP) _(실험적임)_ -You can handle all the results of these metrics using the `web-vital` label: +`web-vital` 라벨을 사용하여 매트릭을 처리할 수 있습니다. ```js export function reportWebVitals(metric) { if (metric.label === 'web-vital') { - console.log(metric) // The metric object ({ id, name, startTime, value, label }) is logged to the console + console.log(metric) // 매트릭 객체인 ({ id, name, startTiem, value, label })를 콘솔에 기록합니다. } } ``` - -There's also the option of handling each of the metrics separately: +또한 매트릭을 개별적으로 처리할 수 있는 옵션이 존재합니다. ```js export function reportWebVitals(metric) { switch (metric.name) { case 'FCP': - // handle FCP results + // FCP 결과를 처리합니다. break case 'LCP': - // handle LCP results + // LCP 결과를 처리합니다. break case 'CLS': - // handle CLS results + // CLS 결과를 처리합니다. break case 'FID': - // handle FID results + // FID 결과를 처리합니다. break case 'TTFB': - // handle TTFB results + // TTFB 결과를 처리합니다. break case 'INP': - // handle INP results (note: INP is still an experimental metric) + // INP 결과를 처리합니다. (참고: INP는 아직 실험적인 매트릭스입니다.) break default: break @@ -99,44 +94,40 @@ export function reportWebVitals(metric) { } ``` -A third-party library, [web-vitals](https://github.com/GoogleChrome/web-vitals), is used to measure -these metrics. Browser compatibility depends on the particular metric, so refer to the [Browser -Support](https://github.com/GoogleChrome/web-vitals#browser-support) section to find out which -browsers are supported. +이러한 매트릭을 측정하기 위하여 타 사가 제공하는 [web-vitals](https://github.com/GoogleChrome/web-vitals) 라이브러리를 사용합니다. 브라우저의 호환성은 매트릭스에 따라 다르게 작동하기 때문에 매트릭스가 지원되는 브라우저에 대하여 알아보기 위해서는 [Browser +Support](https://github.com/GoogleChrome/web-vitals#browser-support)를 참고하세요. -## Custom metrics +## 사용자 정의 매트릭스 -In addition to the core metrics listed above, there are some additional custom metrics that -measure the time it takes for the page to hydrate and render: +위에서 언급한 기본적인 매트릭스 외에도, 페이지를 hydrate하고 랜더링하는 데 걸리는 시간을 측정하는 추가적인 사용자 정의 매트릭스가 있습니다. -- `Next.js-hydration`: Length of time it takes for the page to start and finish hydrating (in ms) -- `Next.js-route-change-to-render`: Length of time it takes for a page to start rendering after a - route change (in ms) -- `Next.js-render`: Length of time it takes for a page to finish render after a route change (in ms) +- `Next.js-hydration`: 페이지가 hydrate를 시작하고 완료될 때까지 걸리는 시간입니다. (밀리초 단위) +- `Next.js-route-change-to-render`: 페이지의 라우트가 변경된 이후 랜더링을 시작하는 데 걸리는 시간입니다. (밀리초 단위) +- `Next.js-render`: 라우트가 변경된 이후 페이지가 랜더링을 완료하는 데 걸리는 시간입니다. (밀리초 단위) -You can handle all the results of these metrics using the `custom` label: +매트릭의 결과를 `custom` 라벨을 사용하여 처리할 수 있습니다. ```js export function reportWebVitals(metric) { if (metric.label === 'custom') { - console.log(metric) // The metric object ({ id, name, startTime, value, label }) is logged to the console + console.log(metric) // 매트릭 객체인 ({ id, name, startTiem, value, label })를 콘솔에 기록합니다. } } ``` -There's also the option of handling each of the metrics separately: +또한 매트릭을 개별적으로 처리할 수 있는 옵션이 존재합니다. ```js export function reportWebVitals(metric) { switch (metric.name) { case 'Next.js-hydration': - // handle hydration results + // hydration 결과 처리 break case 'Next.js-route-change-to-render': - // handle route-change to render results + // route-change to render 결과 처리 break case 'Next.js-render': - // handle render results + // render 결과 처리 break default: break @@ -144,19 +135,17 @@ export function reportWebVitals(metric) { } ``` -These metrics work in all browsers that support the [User Timing API](https://caniuse.com/#feat=user-timing). +이러한 매트릭은 [User Timing API](https://caniuse.com/#feat=user-timing)을 지원하는 모든 브러우저에서 동작합니다. -## Sending results to external systems +## 외부 시스템으로 결과를 전송하기 -With the relay function, you can send results to any endpoint to measure and track -real user performance on your site. For example: +릴레이 함수를 사용한다면 결과를 원하는 엔드포인트로 전송하여 사이트에서 실제 사용자를 대상으로 한 성능을 측정하고 추적할 수 있습니다. 예를 들어 ```js export function reportWebVitals(metric) { const body = JSON.stringify(metric) const url = 'https://example.com/analytics' - - // Use `navigator.sendBeacon()` if available, falling back to `fetch()`. + // `navigator.sendBeacon()`을 사용할 수 있는 경우에는 해당 메서드를 이용하고, 그렇지 않은 경우에는 `fetch()`를 사용합니다. if (navigator.sendBeacon) { navigator.sendBeacon(url, body) } else { @@ -165,29 +154,28 @@ export function reportWebVitals(metric) { } ``` -> **Good to know**: If you use [Google Analytics](https://analytics.google.com/analytics/web/), using the -> `id` value can allow you to construct metric distributions manually (to calculate percentiles, -> etc.) +> **알아두면 좋은 내용**: 만약 [Google Analytics](https://analytics.google.com/analytics/web/)을 사용한다면, `id` 값으로 매트릭에 대한 분포를 수동으로 생성할 수 있습니다. (백분위를 계산하는 등) +> > > ```js > export function reportWebVitals({ id, name, label, value }) { -> // Use `window.gtag` if you initialized Google Analytics as this example: +> // 만약 Google Analytics를 해당 예시와 같이 초기화하였다면, `window.gtag`를 사용합니다. > // https://github.com/vercel/next.js/blob/canary/examples/with-google-analytics/pages/_app.js > window.gtag('event', name, { > event_category: > label === 'web-vital' ? 'Web Vitals' : 'Next.js custom metric', -> value: Math.round(name === 'CLS' ? value * 1000 : value), // values must be integers -> event_label: id, // id unique to current page load -> non_interaction: true, // avoids affecting bounce rate. +> value: Math.round(name === 'CLS' ? value * 1000 : value), // 값은 정수로 지정합니다. +> event_label: id, // 페이지 로드에 고유한 id입니다. +> non_interaction: true, // 바운스 비율에 영향을 주지 않도록 합니다. > }) > } > ``` > -> Read more about [sending results to Google Analytics](https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics). +> 더 많은 정보는 [Google Analytics에 결과 보내기](https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics)를 참고해주세요. -## TypeScript +## 타입스크립트 -If you are using TypeScript, you can use the built-in type `NextWebVitalsMetric`: +타입스크립트를 사용하는 경우 내장된 타입인 `NextWebVitalsMetric`을 이용합니다. ```tsx filename="pages/_app.tsx" switcher import type { AppProps, NextWebVitalsMetric } from 'next/app' From 55abbb5eff77dc2e7ee623de3a2506e40236e904 Mon Sep 17 00:00:00 2001 From: Eugene Kim Date: Tue, 4 Jul 2023 17:03:49 +0900 Subject: [PATCH 2/3] =?UTF-8?q?docs:=20=EA=B0=80=EC=9D=B4=EB=93=9C=20?= =?UTF-8?q?=EB=AC=B8=EC=84=9C=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../05-optimizing/07-analytics.mdx | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx b/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx index 15ee89ce1..9e3d991fc 100644 --- a/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx +++ b/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx @@ -11,7 +11,7 @@ description: Next.js Speed Insights를 사용하여 페이지의 성능을 측 -## 직접 구현해보기 +## 직접 구현해 보기 먼저, [커스텀 앱](/docs/pages/building-your-application/routing/custom-app) 컴포넌트를 생성하고, `reportWebVitals` 함수를 정의합니다. @@ -26,17 +26,17 @@ function MyApp({ Component, pageProps }) { export default MyApp ``` -함수는 페이지에 존재하는 모든 매트릭의 최종적인 값에 대한 계산이 완료되었을 때 실행됩니다. 이에 대한 결과 일부를 콘솔에 기록하거나 특정 엔드포인트로 전송하는 데 사용할 수 있습니다. +함수는 페이지에 존재하는 모든 메트릭의 최종적인 값에 대한 계산이 완료되었을 때 실행됩니다. 이에 대한 결과 일부를 콘솔에 기록하거나 특정 엔드포인트로 전송하는 데 사용할 수 있습니다. -`metric` 객체는 다음과 같이 여러 속성으로 구성됩니다. +메트릭 객체는 다음과 같이 여러 속성으로 구성됩니다. -- `id`: 현재 로드된 페이지의 맥락 속에서 사용하는 매트릭의 고유 식별자입니다. -- `name`: 매트릭의 이름 -- `startTime`: 성능 엔트리에서 첫 번째로 기록된 타임스탬프입니다. 이는 [밀리초](https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp) 단위입니다. (해당되는 경우) +- `id`: 현재 로드된 페이지의 맥락 속에서 사용하는 메트릭의 고유 식별자입니다. +- `name`: 메트릭의 이름 +- `startTime`: 성능 엔트리에서 첫 번째로 기록된 타임스탬프입니다. 이는 [밀리초](https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp) 단위입니다. (해당하는 경우) - `value`: 성능 엔트리의 값 또는 지속 시간입니다. 이는 [밀리초](https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp) 단위입니다. -- `label`: 매트릭의 종류 (`web-vital` 또는 `custom`) +- `label`: 메트릭의 종류 (`web-vital` 또는 `custom`) -성능 추적에 사용할 수 있는 두 가지 유형의 매트릭입니다. +아래는 성능 추적에 사용할 수 있는 두 가지 유형의 메트릭입니다. - Web Vitals - Custom metrics @@ -45,7 +45,7 @@ export default MyApp ## Web Vitals -[Web Vitals](https://web.dev/vitals/)은 웹 페이지에 대한 사용자 경험(UX)을 측정하기 위하여 구성된 유용한 매트릭의 집합입니다. 다음과 같은 web vitals가 모두 포함됩니다. +[Web Vitals](https://web.dev/vitals/)은 웹 페이지에 대한 사용자 경험(UX)을 측정하기 위하여 구성된 유용한 메트릭의 집합입니다. 다음과 같은 web vitals가 모두 포함됩니다. - [Time to First Byte](https://developer.mozilla.org/en-US/docs/Glossary/Time_to_first_byte) (TTFB) - [First Contentful Paint](https://developer.mozilla.org/en-US/docs/Glossary/First_contentful_paint) (FCP) @@ -56,16 +56,16 @@ export default MyApp -`web-vital` 라벨을 사용하여 매트릭을 처리할 수 있습니다. +`web-vital` 라벨을 사용하여 메트릭을 처리할 수 있습니다. ```js export function reportWebVitals(metric) { if (metric.label === 'web-vital') { - console.log(metric) // 매트릭 객체인 ({ id, name, startTiem, value, label })를 콘솔에 기록합니다. + console.log(metric) // 메트릭 객체인 ({ id, name, startTiem, value, label })를 콘솔에 기록합니다. } } ``` -또한 매트릭을 개별적으로 처리할 수 있는 옵션이 존재합니다. +또한 메트릭을 개별적으로 처리할 수 있는 옵션이 존재합니다. ```js export function reportWebVitals(metric) { @@ -86,7 +86,7 @@ export function reportWebVitals(metric) { // TTFB 결과를 처리합니다. break case 'INP': - // INP 결과를 처리합니다. (참고: INP는 아직 실험적인 매트릭스입니다.) + // INP 결과를 처리합니다. (참고: INP는 아직 실험적인 메트릭스입니다.) break default: break @@ -94,28 +94,28 @@ export function reportWebVitals(metric) { } ``` -이러한 매트릭을 측정하기 위하여 타 사가 제공하는 [web-vitals](https://github.com/GoogleChrome/web-vitals) 라이브러리를 사용합니다. 브라우저의 호환성은 매트릭스에 따라 다르게 작동하기 때문에 매트릭스가 지원되는 브라우저에 대하여 알아보기 위해서는 [Browser +이러한 메트릭을 측정하기 위하여 타 사가 제공하는 [web-vitals](https://github.com/GoogleChrome/web-vitals) 라이브러리를 사용합니다. 브라우저의 호환성은 메트릭스에 따라 다르게 작동하기 때문에 메트릭스가 지원되는 브라우저에 대하여 알아보기 위해서는 [Browser Support](https://github.com/GoogleChrome/web-vitals#browser-support)를 참고하세요. -## 사용자 정의 매트릭스 +## 사용자 정의 메트릭스 -위에서 언급한 기본적인 매트릭스 외에도, 페이지를 hydrate하고 랜더링하는 데 걸리는 시간을 측정하는 추가적인 사용자 정의 매트릭스가 있습니다. +위에서 언급한 기본적인 메트릭스 외에도, 페이지를 hydrate하고 렌더링하는 데 걸리는 시간을 측정하는 추가적인 사용자 정의 메트릭스가 있습니다. - `Next.js-hydration`: 페이지가 hydrate를 시작하고 완료될 때까지 걸리는 시간입니다. (밀리초 단위) -- `Next.js-route-change-to-render`: 페이지의 라우트가 변경된 이후 랜더링을 시작하는 데 걸리는 시간입니다. (밀리초 단위) -- `Next.js-render`: 라우트가 변경된 이후 페이지가 랜더링을 완료하는 데 걸리는 시간입니다. (밀리초 단위) +- `Next.js-route-change-to-render`: 페이지의 라우트가 변경된 이후 렌더링을 시작하는 데 걸리는 시간입니다. (밀리초 단위) +- `Next.js-render`: 라우트가 변경된 이후 페이지가 렌더링을 완료하는 데 걸리는 시간입니다. (밀리초 단위) -매트릭의 결과를 `custom` 라벨을 사용하여 처리할 수 있습니다. +메트릭의 결과를 `custom` 라벨을 사용하여 처리할 수 있습니다. ```js export function reportWebVitals(metric) { if (metric.label === 'custom') { - console.log(metric) // 매트릭 객체인 ({ id, name, startTiem, value, label })를 콘솔에 기록합니다. + console.log(metric) // 메트릭 객체인 ({ id, name, startTiem, value, label })를 콘솔에 기록합니다. } } ``` -또한 매트릭을 개별적으로 처리할 수 있는 옵션이 존재합니다. +또한 메트릭을 개별적으로 처리할 수 있는 옵션이 존재합니다. ```js export function reportWebVitals(metric) { @@ -135,7 +135,7 @@ export function reportWebVitals(metric) { } ``` -이러한 매트릭은 [User Timing API](https://caniuse.com/#feat=user-timing)을 지원하는 모든 브러우저에서 동작합니다. +이러한 메트릭은 [User Timing API](https://caniuse.com/#feat=user-timing)을 지원하는 모든 브러우저에서 동작합니다. ## 외부 시스템으로 결과를 전송하기 @@ -154,12 +154,12 @@ export function reportWebVitals(metric) { } ``` -> **알아두면 좋은 내용**: 만약 [Google Analytics](https://analytics.google.com/analytics/web/)을 사용한다면, `id` 값으로 매트릭에 대한 분포를 수동으로 생성할 수 있습니다. (백분위를 계산하는 등) +> **알아두면 좋은 내용**: [Google Analytics](https://analytics.google.com/analytics/web/)을 사용한다면, `id` 값으로 메트릭에 대한 분포를 수동으로 생성할 수 있습니다. (백분위를 계산하는 등) > > > ```js > export function reportWebVitals({ id, name, label, value }) { -> // 만약 Google Analytics를 해당 예시와 같이 초기화하였다면, `window.gtag`를 사용합니다. +> // Google Analytics를 해당 예시와 같이 초기화하였다면, `window.gtag`를 사용합니다. > // https://github.com/vercel/next.js/blob/canary/examples/with-google-analytics/pages/_app.js > window.gtag('event', name, { > event_category: @@ -171,7 +171,7 @@ export function reportWebVitals(metric) { > } > ``` > -> 더 많은 정보는 [Google Analytics에 결과 보내기](https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics)를 참고해주세요. +> 더 많은 정보는 [Google Analytics에 결과 보내기](https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics)를 참고해 주세요. ## 타입스크립트 From 35af70a2ac396aed8ca81949869ac0da057f593e Mon Sep 17 00:00:00 2001 From: Eugene Kim Date: Tue, 4 Jul 2023 17:15:31 +0900 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20prettier=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../05-optimizing/07-analytics.mdx | 37 +++++++-------- .../01-metadata/app-icons.mdx | 40 ++++++++-------- .../04-styling/03-css-in-js.mdx | 27 +++++++---- .../05-optimizing/06-lazy-loading.mdx | 2 +- .../06-configuring/12-error-handling.mdx | 2 +- examples/blog-starter/components/alert.tsx | 8 ++-- examples/blog-starter/components/avatar.tsx | 2 +- .../blog-starter/components/cover-image.tsx | 4 +- examples/blog-starter/components/footer.tsx | 10 ++-- examples/blog-starter/components/header.tsx | 2 +- .../blog-starter/components/hero-post.tsx | 8 ++-- examples/blog-starter/components/intro.tsx | 8 ++-- .../components/markdown-styles.module.css | 4 +- .../blog-starter/components/more-stories.tsx | 4 +- .../blog-starter/components/post-body.tsx | 2 +- .../blog-starter/components/post-header.tsx | 8 ++-- .../blog-starter/components/post-preview.tsx | 6 +-- .../blog-starter/components/post-title.tsx | 2 +- .../components/section-separator.tsx | 2 +- .../components/comment/form.tsx | 8 ++-- .../components/comment/list.tsx | 2 +- .../components/container.tsx | 2 +- examples/blog-with-comment/pages/index.tsx | 2 +- .../blog-with-comment/pages/posts/[slug].tsx | 2 +- .../blog-with-comment/pages/posts/index.tsx | 2 +- examples/cms-agilitycms/components/alert.tsx | 4 +- examples/cms-agilitycms/components/avatar.tsx | 2 +- examples/cms-agilitycms/components/footer.tsx | 10 ++-- examples/cms-agilitycms/components/header.tsx | 2 +- .../cms-agilitycms/components/hero-post.tsx | 8 ++-- examples/cms-agilitycms/components/intro.tsx | 10 ++-- .../components/markdown-styles.module.css | 4 +- .../components/more-stories.tsx | 4 +- .../cms-agilitycms/components/post-body.tsx | 2 +- .../cms-agilitycms/components/post-header.tsx | 8 ++-- .../components/post-preview.tsx | 6 +-- .../cms-agilitycms/components/post-title.tsx | 2 +- examples/cms-builder-io/components/alert.js | 4 +- examples/cms-builder-io/components/avatar.js | 2 +- examples/cms-builder-io/components/footer.js | 10 ++-- examples/cms-builder-io/components/header.js | 2 +- .../cms-builder-io/components/hero-post.js | 8 ++-- examples/cms-builder-io/components/intro.js | 10 ++-- .../cms-builder-io/components/more-stories.js | 4 +- .../cms-builder-io/components/post-body.js | 2 +- .../cms-builder-io/components/post-header.js | 8 ++-- .../cms-builder-io/components/post-preview.js | 6 +-- .../cms-builder-io/components/post-title.js | 2 +- .../components/landing-page-sections/hero.js | 2 +- .../two-column-with-image.js | 2 +- .../components/main-menu/main-menu.js | 2 +- .../components/missing-token-section.js | 2 +- examples/cms-contentful/components/alert.js | 4 +- examples/cms-contentful/components/avatar.js | 2 +- examples/cms-contentful/components/footer.js | 10 ++-- examples/cms-contentful/components/header.js | 2 +- .../cms-contentful/components/hero-post.js | 8 ++-- examples/cms-contentful/components/intro.js | 10 ++-- .../components/markdown-styles.module.css | 4 +- .../cms-contentful/components/more-stories.js | 4 +- .../cms-contentful/components/post-body.js | 2 +- .../cms-contentful/components/post-header.js | 8 ++-- .../cms-contentful/components/post-preview.js | 6 +-- .../cms-contentful/components/post-title.js | 2 +- examples/cms-cosmic/components/alert.tsx | 4 +- examples/cms-cosmic/components/avatar.tsx | 2 +- examples/cms-cosmic/components/footer.tsx | 10 ++-- examples/cms-cosmic/components/header.tsx | 2 +- examples/cms-cosmic/components/hero-post.tsx | 8 ++-- examples/cms-cosmic/components/intro.tsx | 10 ++-- .../components/markdown-styles.module.css | 4 +- .../cms-cosmic/components/more-stories.tsx | 4 +- examples/cms-cosmic/components/post-body.tsx | 2 +- .../cms-cosmic/components/post-header.tsx | 8 ++-- .../cms-cosmic/components/post-preview.tsx | 6 +-- examples/cms-cosmic/components/post-title.tsx | 2 +- examples/cms-datocms/components/alert.js | 4 +- examples/cms-datocms/components/avatar.js | 2 +- examples/cms-datocms/components/footer.js | 10 ++-- examples/cms-datocms/components/header.js | 2 +- examples/cms-datocms/components/hero-post.js | 8 ++-- examples/cms-datocms/components/intro.js | 10 ++-- .../components/markdown-styles.module.css | 4 +- .../cms-datocms/components/more-stories.js | 4 +- examples/cms-datocms/components/post-body.js | 2 +- .../cms-datocms/components/post-header.js | 8 ++-- .../cms-datocms/components/post-preview.js | 6 +-- examples/cms-datocms/components/post-title.js | 2 +- examples/cms-dotcms/components/alert.tsx | 4 +- examples/cms-dotcms/components/avatar.tsx | 2 +- examples/cms-dotcms/components/footer.tsx | 10 ++-- examples/cms-dotcms/components/header.tsx | 2 +- examples/cms-dotcms/components/hero-post.tsx | 2 +- examples/cms-dotcms/components/intro.tsx | 10 ++-- .../cms-dotcms/components/more-stories.tsx | 2 +- examples/cms-dotcms/components/post-body.tsx | 4 +- .../cms-dotcms/components/post-header.tsx | 4 +- examples/cms-dotcms/components/post-title.tsx | 2 +- examples/cms-drupal/components/alert.js | 4 +- examples/cms-drupal/components/avatar.js | 4 +- examples/cms-drupal/components/footer.js | 10 ++-- examples/cms-drupal/components/header.js | 2 +- examples/cms-drupal/components/hero-post.js | 8 ++-- examples/cms-drupal/components/intro.js | 10 ++-- .../cms-drupal/components/more-stories.js | 4 +- examples/cms-drupal/components/post-body.js | 2 +- .../components/post-body.module.css | 10 ++-- examples/cms-drupal/components/post-header.js | 8 ++-- .../cms-drupal/components/post-preview.js | 6 +-- examples/cms-drupal/components/post-title.js | 2 +- examples/cms-drupal/components/tags.js | 2 +- examples/cms-enterspeed/components/alert.tsx | 4 +- examples/cms-enterspeed/components/avatar.tsx | 2 +- examples/cms-enterspeed/components/footer.tsx | 10 ++-- examples/cms-enterspeed/components/header.tsx | 2 +- .../cms-enterspeed/components/hero-post.tsx | 8 ++-- examples/cms-enterspeed/components/intro.tsx | 10 ++-- .../components/more-stories.tsx | 4 +- .../components/post-body.module.css | 10 ++-- .../cms-enterspeed/components/post-body.tsx | 2 +- .../cms-enterspeed/components/post-header.tsx | 8 ++-- .../components/post-preview.tsx | 6 +-- .../cms-enterspeed/components/post-title.tsx | 2 +- examples/cms-enterspeed/components/tags.tsx | 2 +- examples/cms-enterspeed/styles/index.css | 12 ++--- examples/cms-ghost/components/alert.js | 4 +- examples/cms-ghost/components/avatar.js | 2 +- examples/cms-ghost/components/cover-image.js | 2 +- examples/cms-ghost/components/footer.js | 10 ++-- examples/cms-ghost/components/header.js | 2 +- examples/cms-ghost/components/hero-post.js | 8 ++-- examples/cms-ghost/components/intro.js | 10 ++-- .../components/markdown-styles.module.css | 4 +- examples/cms-ghost/components/more-stories.js | 4 +- examples/cms-ghost/components/post-body.js | 2 +- examples/cms-ghost/components/post-header.js | 8 ++-- examples/cms-ghost/components/post-preview.js | 6 +-- examples/cms-ghost/components/post-title.js | 2 +- examples/cms-graphcms/components/alert.js | 4 +- examples/cms-graphcms/components/avatar.js | 2 +- examples/cms-graphcms/components/footer.js | 10 ++-- examples/cms-graphcms/components/header.js | 2 +- examples/cms-graphcms/components/hero-post.js | 2 +- examples/cms-graphcms/components/intro.js | 10 ++-- .../cms-graphcms/components/more-stories.js | 4 +- examples/cms-graphcms/components/post-body.js | 2 +- .../cms-graphcms/components/post-header.js | 8 ++-- .../cms-graphcms/components/post-title.js | 2 +- examples/cms-kontent-ai/components/alert.tsx | 4 +- examples/cms-kontent-ai/components/avatar.tsx | 2 +- examples/cms-kontent-ai/components/footer.tsx | 10 ++-- examples/cms-kontent-ai/components/header.tsx | 2 +- .../cms-kontent-ai/components/hero-post.tsx | 8 ++-- examples/cms-kontent-ai/components/intro.tsx | 10 ++-- .../components/markdown-styles.module.css | 4 +- .../components/more-stories.tsx | 4 +- .../cms-kontent-ai/components/post-body.tsx | 2 +- .../cms-kontent-ai/components/post-header.tsx | 8 ++-- .../components/post-preview.tsx | 6 +-- .../cms-kontent-ai/components/post-title.tsx | 2 +- examples/cms-prepr/components/alert.js | 4 +- examples/cms-prepr/components/avatar.js | 2 +- examples/cms-prepr/components/footer.js | 10 ++-- examples/cms-prepr/components/header.js | 2 +- examples/cms-prepr/components/hero-post.js | 2 +- examples/cms-prepr/components/intro.js | 10 ++-- examples/cms-prepr/components/more-stories.js | 4 +- examples/cms-prepr/components/post-body.js | 2 +- examples/cms-prepr/components/post-header.js | 8 ++-- examples/cms-prepr/components/post-title.js | 2 +- examples/cms-prismic/components/alert.tsx | 4 +- examples/cms-prismic/components/avatar.tsx | 2 +- examples/cms-prismic/components/footer.tsx | 10 ++-- examples/cms-prismic/components/header.tsx | 2 +- examples/cms-prismic/components/hero-post.tsx | 8 ++-- examples/cms-prismic/components/intro.tsx | 10 ++-- .../cms-prismic/components/more-stories.tsx | 4 +- examples/cms-prismic/components/post-body.tsx | 2 +- .../cms-prismic/components/post-header.tsx | 8 ++-- .../cms-prismic/components/post-preview.tsx | 6 +-- .../cms-prismic/components/post-title.tsx | 2 +- examples/cms-prismic/slices/Text/index.tsx | 4 +- examples/cms-sanity/components/alert.js | 4 +- examples/cms-sanity/components/avatar.js | 2 +- examples/cms-sanity/components/cover-image.js | 2 +- examples/cms-sanity/components/footer.js | 10 ++-- examples/cms-sanity/components/header.js | 2 +- examples/cms-sanity/components/hero-post.js | 2 +- examples/cms-sanity/components/intro.js | 10 ++-- .../components/markdown-styles.module.css | 4 +- .../cms-sanity/components/more-stories.js | 4 +- examples/cms-sanity/components/post-body.js | 2 +- examples/cms-sanity/components/post-header.js | 8 ++-- examples/cms-sanity/components/post-title.js | 2 +- examples/cms-sitefinity/components/alert.tsx | 8 ++-- examples/cms-sitefinity/components/avatar.tsx | 2 +- .../cms-sitefinity/components/cover-image.tsx | 2 +- examples/cms-sitefinity/components/footer.tsx | 10 ++-- examples/cms-sitefinity/components/header.tsx | 2 +- .../cms-sitefinity/components/hero-post.tsx | 8 ++-- examples/cms-sitefinity/components/intro.tsx | 8 ++-- .../components/markdown-styles.module.css | 4 +- .../components/more-stories.tsx | 4 +- .../cms-sitefinity/components/post-body.tsx | 2 +- .../cms-sitefinity/components/post-header.tsx | 8 ++-- .../components/post-preview.tsx | 6 +-- .../cms-sitefinity/components/post-title.tsx | 2 +- .../components/section-separator.tsx | 2 +- examples/cms-storyblok/components/alert.js | 4 +- examples/cms-storyblok/components/avatar.js | 2 +- examples/cms-storyblok/components/footer.js | 10 ++-- examples/cms-storyblok/components/header.js | 2 +- .../cms-storyblok/components/hero-post.js | 8 ++-- examples/cms-storyblok/components/intro.js | 10 ++-- .../components/markdown-styles.module.css | 4 +- .../cms-storyblok/components/more-stories.js | 4 +- .../cms-storyblok/components/post-body.js | 2 +- .../cms-storyblok/components/post-header.js | 8 ++-- .../cms-storyblok/components/post-preview.js | 6 +-- .../cms-storyblok/components/post-title.js | 2 +- examples/cms-takeshape/components/alert.js | 4 +- examples/cms-takeshape/components/avatar.js | 2 +- examples/cms-takeshape/components/footer.js | 10 ++-- examples/cms-takeshape/components/header.js | 2 +- .../cms-takeshape/components/hero-post.js | 8 ++-- examples/cms-takeshape/components/intro.js | 10 ++-- .../components/markdown-styles.module.css | 4 +- .../cms-takeshape/components/more-stories.js | 4 +- .../cms-takeshape/components/post-body.js | 2 +- .../cms-takeshape/components/post-header.js | 8 ++-- .../cms-takeshape/components/post-preview.js | 6 +-- .../cms-takeshape/components/post-title.js | 2 +- examples/cms-tina/components/alert.js | 4 +- examples/cms-tina/components/avatar.js | 2 +- examples/cms-tina/components/cover-image.js | 2 +- examples/cms-tina/components/footer.js | 10 ++-- examples/cms-tina/components/header.js | 2 +- examples/cms-tina/components/hero-post.js | 8 ++-- examples/cms-tina/components/intro.js | 8 ++-- .../components/markdown-styles.module.css | 4 +- examples/cms-tina/components/more-stories.js | 4 +- examples/cms-tina/components/post-body.js | 2 +- examples/cms-tina/components/post-header.js | 8 ++-- examples/cms-tina/components/post-preview.js | 6 +-- examples/cms-tina/components/post-title.js | 2 +- .../cms-umbraco-heartcore/components/alert.js | 4 +- .../components/avatar.js | 2 +- .../components/footer.js | 10 ++-- .../components/header.js | 2 +- .../components/hero-post.js | 2 +- .../cms-umbraco-heartcore/components/intro.js | 10 ++-- .../components/more-stories.js | 4 +- .../components/post-body.js | 2 +- .../components/post-header.js | 8 ++-- .../components/post-title.js | 2 +- examples/cms-webiny/components/alert.tsx | 6 +-- examples/cms-webiny/components/avatar.tsx | 2 +- examples/cms-webiny/components/container.tsx | 2 +- .../cms-webiny/components/cover-image.tsx | 2 +- examples/cms-webiny/components/footer.tsx | 8 ++-- examples/cms-webiny/components/hero-post.tsx | 2 +- examples/cms-webiny/components/intro.tsx | 10 ++-- .../cms-webiny/components/more-stories.tsx | 2 +- examples/cms-webiny/components/post-body.tsx | 2 +- .../cms-webiny/components/post-header.tsx | 8 ++-- examples/cms-webiny/components/post-title.tsx | 2 +- .../components/section-separator.tsx | 2 +- examples/cms-wordpress/components/alert.tsx | 4 +- examples/cms-wordpress/components/avatar.tsx | 2 +- examples/cms-wordpress/components/footer.tsx | 10 ++-- examples/cms-wordpress/components/header.tsx | 2 +- .../cms-wordpress/components/hero-post.tsx | 8 ++-- examples/cms-wordpress/components/intro.tsx | 10 ++-- .../cms-wordpress/components/more-stories.tsx | 4 +- .../components/post-body.module.css | 10 ++-- .../cms-wordpress/components/post-body.tsx | 2 +- .../cms-wordpress/components/post-header.tsx | 8 ++-- .../cms-wordpress/components/post-preview.tsx | 6 +-- .../cms-wordpress/components/post-title.tsx | 2 +- examples/cms-wordpress/components/tags.tsx | 2 +- examples/cms-wordpress/styles/index.css | 12 ++--- examples/radix-ui/pages/index.tsx | 28 +++++------ examples/with-ant-design/pages/index.tsx | 4 +- .../components/SharedModal.tsx | 2 +- examples/with-cloudinary/pages/index.tsx | 4 +- .../with-fauna/components/LoadingSpinner.js | 2 +- examples/with-fauna/pages/index.js | 20 ++++---- examples/with-grafbase/app/layout.tsx | 14 +++--- examples/with-mdbreact/pages/index.js | 4 +- examples/with-mongodb-mongoose/pages/_app.js | 2 +- examples/with-mysql/components/Product.js | 10 ++-- examples/with-mysql/pages/index.js | 8 ++-- .../with-next-page-transitions/pages/about.js | 2 +- .../with-next-page-transitions/pages/index.js | 2 +- examples/with-redis/pages/index.tsx | 46 +++++++++---------- examples/with-sfcc/components/ProductCard.tsx | 2 +- examples/with-supabase/app/layout.tsx | 2 +- examples/with-supabase/app/login/page.tsx | 16 +++---- examples/with-supabase/app/page.tsx | 22 ++++----- examples/with-turbopack/app/layout.tsx | 4 +- examples/with-turbopack/app/not-found.tsx | 2 +- .../[subCategorySlug]/not-found.tsx | 2 +- .../not-found/[categorySlug]/not-found.tsx | 2 +- .../app/not-found/not-found.tsx | 2 +- examples/with-turbopack/app/page.tsx | 2 +- examples/with-turbopack/app/snippets/page.tsx | 2 +- examples/with-turbopack/app/ssg/[id]/page.tsx | 2 +- .../app/streaming/_components/add-to-cart.tsx | 2 +- .../app/streaming/_components/header.tsx | 4 +- .../app/styling/tailwind/page.tsx | 2 +- examples/with-turbopack/pages/_document.tsx | 2 +- examples/with-turbopack/ui/boundary.tsx | 2 +- examples/with-turbopack/ui/byline.tsx | 2 +- examples/with-turbopack/ui/component-tree.tsx | 8 ++-- .../ui/page-directory/layout.tsx | 6 +-- .../ui/page-directory/product-pricing.tsx | 2 +- examples/with-turbopack/ui/ping.tsx | 4 +- examples/with-turbopack/ui/product-card.tsx | 2 +- examples/with-turbopack/ui/product-deal.tsx | 2 +- .../ui/product-low-stock-warning.tsx | 4 +- .../with-userbase/components/modal/index.js | 14 +++--- .../with-userbase/components/nav/index.js | 6 +-- .../components/todo-form/index.js | 10 ++-- examples/with-userbase/pages/index.js | 4 +- examples/with-userbase/styles/button.css | 2 +- .../templates/app-tw/js/app/page.js | 2 +- .../templates/app-tw/ts/app/page.tsx | 2 +- .../templates/default-tw/js/pages/index.js | 2 +- .../templates/default-tw/ts/pages/index.tsx | 2 +- .../app/(post)/components/a.tsx | 2 +- .../app/(post)/components/blockquote.tsx | 2 +- .../app/(post)/components/callout.tsx | 4 +- .../app/(post)/components/caption.tsx | 2 +- .../app/(post)/components/footnotes.tsx | 4 +- .../app/(post)/components/h1.tsx | 2 +- .../app/(post)/components/h2.tsx | 2 +- .../app/(post)/components/h3.tsx | 2 +- .../app/(post)/components/hr.tsx | 2 +- .../app/(post)/components/image.tsx | 2 +- .../app/(post)/components/li.tsx | 6 +-- .../app/(post)/components/ol.tsx | 2 +- .../app/(post)/components/snippet.tsx | 6 +-- .../app/(post)/components/ul.tsx | 2 +- .../basic/tailwind-jit/pages/index.js | 16 +++---- .../app-dir/front-redirect-issue/app/page.tsx | 2 +- .../e2e/postcss-config-cjs/app/pages/index.js | 18 ++++---- .../pages/index.js | 4 +- 347 files changed, 926 insertions(+), 916 deletions(-) diff --git a/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx b/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx index 9e3d991fc..cf074a7cc 100644 --- a/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx +++ b/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx @@ -3,17 +3,17 @@ title: Analytics description: Next.js Speed Insights를 사용하여 페이지의 성능을 측정하고 추적할 수 있습니다. --- -[Next.js Speed Insights](https://nextjs.org/analytics)를 사용하면 다양한 지표를 사용하여 페이지의 성능을 측정하고 분석할 수 있습니다. +[Next.js Speed Insights](https://nextjs.org/analytics)를 사용하면 다양한 지표를 사용하여 페이지의 성능을 측정하고 분석할 수 있습니다. -[Vercel deployments](https://vercel.com/docs/concepts/speed-insights?utm_source=next-site&utm_medium=docs&utm_campaign=next-website)에서는 별다른 설정 없이 [Real Experience Score(RES)](https://vercel.com/docs/concepts/speed-insights#core-web-vitals-explained?utm_source=next-site&utm_medium=docs&utm_campaign=next-website)에 대한 정보를 수집할 수 있습니다. +[Vercel deployments](https://vercel.com/docs/concepts/speed-insights?utm_source=next-site&utm_medium=docs&utm_campaign=next-website)에서는 별다른 설정 없이 [Real Experience Score(RES)](https://vercel.com/docs/concepts/speed-insights#core-web-vitals-explained?utm_source=next-site&utm_medium=docs&utm_campaign=next-website)에 대한 정보를 수집할 수 있습니다. -문서의 이후 내용은 Next.js의 Speed Insights에 기본적인 기능으로 사용하고 있는 `relayer`에 대하여 설명합니다. +문서의 이후 내용은 Next.js의 Speed Insights에 기본적인 기능으로 사용하고 있는 `relayer`에 대하여 설명합니다. ## 직접 구현해 보기 -먼저, [커스텀 앱](/docs/pages/building-your-application/routing/custom-app) 컴포넌트를 생성하고, `reportWebVitals` 함수를 정의합니다. +먼저, [커스텀 앱](/docs/pages/building-your-application/routing/custom-app) 컴포넌트를 생성하고, `reportWebVitals` 함수를 정의합니다. ```jsx filename="pages/_app.js" export function reportWebVitals(metric) { @@ -26,6 +26,7 @@ function MyApp({ Component, pageProps }) { export default MyApp ``` + 함수는 페이지에 존재하는 모든 메트릭의 최종적인 값에 대한 계산이 완료되었을 때 실행됩니다. 이에 대한 결과 일부를 콘솔에 기록하거나 특정 엔드포인트로 전송하는 데 사용할 수 있습니다. 메트릭 객체는 다음과 같이 여러 속성으로 구성됩니다. @@ -45,7 +46,7 @@ export default MyApp ## Web Vitals -[Web Vitals](https://web.dev/vitals/)은 웹 페이지에 대한 사용자 경험(UX)을 측정하기 위하여 구성된 유용한 메트릭의 집합입니다. 다음과 같은 web vitals가 모두 포함됩니다. +[Web Vitals](https://web.dev/vitals/)은 웹 페이지에 대한 사용자 경험(UX)을 측정하기 위하여 구성된 유용한 메트릭의 집합입니다. 다음과 같은 web vitals가 모두 포함됩니다. - [Time to First Byte](https://developer.mozilla.org/en-US/docs/Glossary/Time_to_first_byte) (TTFB) - [First Contentful Paint](https://developer.mozilla.org/en-US/docs/Glossary/First_contentful_paint) (FCP) @@ -56,16 +57,17 @@ export default MyApp -`web-vital` 라벨을 사용하여 메트릭을 처리할 수 있습니다. +`web-vital` 라벨을 사용하여 메트릭을 처리할 수 있습니다. ```js export function reportWebVitals(metric) { if (metric.label === 'web-vital') { - console.log(metric) // 메트릭 객체인 ({ id, name, startTiem, value, label })를 콘솔에 기록합니다. + console.log(metric) // 메트릭 객체인 ({ id, name, startTiem, value, label })를 콘솔에 기록합니다. } } ``` -또한 메트릭을 개별적으로 처리할 수 있는 옵션이 존재합니다. + +또한 메트릭을 개별적으로 처리할 수 있는 옵션이 존재합니다. ```js export function reportWebVitals(metric) { @@ -74,13 +76,13 @@ export function reportWebVitals(metric) { // FCP 결과를 처리합니다. break case 'LCP': - // LCP 결과를 처리합니다. + // LCP 결과를 처리합니다. break case 'CLS': - // CLS 결과를 처리합니다. + // CLS 결과를 처리합니다. break case 'FID': - // FID 결과를 처리합니다. + // FID 결과를 처리합니다. break case 'TTFB': // TTFB 결과를 처리합니다. @@ -94,12 +96,12 @@ export function reportWebVitals(metric) { } ``` -이러한 메트릭을 측정하기 위하여 타 사가 제공하는 [web-vitals](https://github.com/GoogleChrome/web-vitals) 라이브러리를 사용합니다. 브라우저의 호환성은 메트릭스에 따라 다르게 작동하기 때문에 메트릭스가 지원되는 브라우저에 대하여 알아보기 위해서는 [Browser +이러한 메트릭을 측정하기 위하여 타 사가 제공하는 [web-vitals](https://github.com/GoogleChrome/web-vitals) 라이브러리를 사용합니다. 브라우저의 호환성은 메트릭스에 따라 다르게 작동하기 때문에 메트릭스가 지원되는 브라우저에 대하여 알아보기 위해서는 [Browser Support](https://github.com/GoogleChrome/web-vitals#browser-support)를 참고하세요. ## 사용자 정의 메트릭스 -위에서 언급한 기본적인 메트릭스 외에도, 페이지를 hydrate하고 렌더링하는 데 걸리는 시간을 측정하는 추가적인 사용자 정의 메트릭스가 있습니다. +위에서 언급한 기본적인 메트릭스 외에도, 페이지를 hydrate하고 렌더링하는 데 걸리는 시간을 측정하는 추가적인 사용자 정의 메트릭스가 있습니다. - `Next.js-hydration`: 페이지가 hydrate를 시작하고 완료될 때까지 걸리는 시간입니다. (밀리초 단위) - `Next.js-route-change-to-render`: 페이지의 라우트가 변경된 이후 렌더링을 시작하는 데 걸리는 시간입니다. (밀리초 단위) @@ -110,12 +112,12 @@ Support](https://github.com/GoogleChrome/web-vitals#browser-support)를 참고 ```js export function reportWebVitals(metric) { if (metric.label === 'custom') { - console.log(metric) // 메트릭 객체인 ({ id, name, startTiem, value, label })를 콘솔에 기록합니다. + console.log(metric) // 메트릭 객체인 ({ id, name, startTiem, value, label })를 콘솔에 기록합니다. } } ``` -또한 메트릭을 개별적으로 처리할 수 있는 옵션이 존재합니다. +또한 메트릭을 개별적으로 처리할 수 있는 옵션이 존재합니다. ```js export function reportWebVitals(metric) { @@ -135,7 +137,7 @@ export function reportWebVitals(metric) { } ``` -이러한 메트릭은 [User Timing API](https://caniuse.com/#feat=user-timing)을 지원하는 모든 브러우저에서 동작합니다. +이러한 메트릭은 [User Timing API](https://caniuse.com/#feat=user-timing)을 지원하는 모든 브러우저에서 동작합니다. ## 외부 시스템으로 결과를 전송하기 @@ -145,7 +147,7 @@ export function reportWebVitals(metric) { export function reportWebVitals(metric) { const body = JSON.stringify(metric) const url = 'https://example.com/analytics' - // `navigator.sendBeacon()`을 사용할 수 있는 경우에는 해당 메서드를 이용하고, 그렇지 않은 경우에는 `fetch()`를 사용합니다. + // `navigator.sendBeacon()`을 사용할 수 있는 경우에는 해당 메서드를 이용하고, 그렇지 않은 경우에는 `fetch()`를 사용합니다. if (navigator.sendBeacon) { navigator.sendBeacon(url, body) } else { @@ -155,7 +157,6 @@ export function reportWebVitals(metric) { ``` > **알아두면 좋은 내용**: [Google Analytics](https://analytics.google.com/analytics/web/)을 사용한다면, `id` 값으로 메트릭에 대한 분포를 수동으로 생성할 수 있습니다. (백분위를 계산하는 등) -> > > ```js > export function reportWebVitals({ id, name, label, value }) { diff --git a/docs/02-app/02-api-reference/02-file-conventions/01-metadata/app-icons.mdx b/docs/02-app/02-api-reference/02-file-conventions/01-metadata/app-icons.mdx index 4d85703ad..5aabfb8c5 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/01-metadata/app-icons.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/01-metadata/app-icons.mdx @@ -19,15 +19,15 @@ description: Favicon, Icon, Apple Icon 파일 컨벤션에 대한 API 레퍼런 Next.js는 파일을 평가하여 앱의 `` 엘리먼트에 해당하는 태그를 자동으로 추가합니다. -| 파일 컨벤션 | 지원하는 파일 타입 | 유효한 위치 | -| --------------------------- | --------------------------------------- | --------------- | -| [`favicon`](#favicon) | `.ico` | `app/` | -| [`icon`](#icon) | `.ico`, `.jpg`, `.jpeg`, `.png`, `.svg` | `app/**/*` | -| [`apple-icon`](#apple-icon) | `.jpg`, `.jpeg`, `.png` | `app/**/*` | +| 파일 컨벤션 | 지원하는 파일 타입 | 유효한 위치 | +| --------------------------- | --------------------------------------- | ----------- | +| [`favicon`](#favicon) | `.ico` | `app/` | +| [`icon`](#icon) | `.ico`, `.jpg`, `.jpeg`, `.png`, `.svg` | `app/**/*` | +| [`apple-icon`](#apple-icon) | `.jpg`, `.jpeg`, `.png` | `app/**/*` | ### `favicon` -`favicon.ico` 이미지 파일을 루트 `/app` 경로 세그먼트에 추가합니다. +`favicon.ico` 이미지 파일을 루트 `/app` 경로 세그먼트에 추가합니다. ```html filename=" 결과" @@ -64,7 +64,7 @@ Next.js는 파일을 평가하여 앱의 `` 엘리먼트에 해당하는 > - 파일 이름에 숫자 접미사를 추가하여 여러 개의 아이콘을 설정할 수 있습니다. 예를 들어 `icon1.png`, `icon2.png` 등과 같이 작성할 수 있습니다. 번호가 매겨진 파일은 사전 순으로 정렬됩니다. > - 파비콘은 루트 `/app` 세그먼트에서만 설정할 수 있습니다. 보다 세분화가 필요한 경우에는 [`icon`](#icon)을 사용할 수 있습니다. > - 적절한 `` 태그 및 `rel`, `href`, `type`, and `sizes` 와 같은 어트리뷰트는 평가된 파일의 아이콘 타입과 메타데이터에 따라 결정됩니다. -> - 예를 들어 32px * 32px 사이즈의 `.png` 파일은 `type="image/png"`과 `sizes="32x32"` 어트리뷰트를 갖습니다. +> - 예를 들어 32px \* 32px 사이즈의 `.png` 파일은 `type="image/png"`과 `sizes="32x32"` 어트리뷰트를 갖습니다. > - `.ico` 아이콘이 `.svg`보다 선호되는 [브라우저 버그를 방지](https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needsa)하기 위해 `sizes="any"` 어트리뷰트가 `favicon.ico` 출력에 추가되었습니다. ## 코드를 사용하여 아이콘 생성 (.js, .ts, .tsx) @@ -73,10 +73,10 @@ Next.js는 파일을 평가하여 앱의 `` 엘리먼트에 해당하는 default exports 함수를 사용하여 `icon` 또는 `apple-icon` 경로를 생성해 앱 아이콘을 만들 수 있습니다. -| 파일 컨벤션 | 지원하는 파일 타입 | -| --------------- | -------------------- | -| `icon` | `.js`, `.ts`, `.tsx` | -| `apple-icon` | `.js`, `.ts`, `.tsx` | +| 파일 컨벤션 | 지원하는 파일 타입 | +| ------------ | -------------------- | +| `icon` | `.js`, `.ts`, `.tsx` | +| `apple-icon` | `.js`, `.ts`, `.tsx` | 아이콘을 생성하는 가장 쉬운 방법은 `next/server`의 [`ImageResponse`](/docs/app/api-reference/functions/image-response) API를 사용하는 것입니다. @@ -116,7 +116,7 @@ export default function Icon() { // ImageResponse 옵션 { // 편의를 위해, 내보낸 아이콘 사이즈 메타데이터를 재사용할 수 있습니다. - // ImageResponse의 너비와 높이도 설정할 수 있습니다. + // ImageResponse의 너비와 높이도 설정할 수 있습니다. ...size, } ) @@ -159,7 +159,7 @@ export default function Icon() { // ImageResponse 옵션 { // 편의를 위해, 내보낸 아이콘 사이즈 메타데이터를 재사용할 수 있습니다. - // ImageResponse의 너비와 높이도 설정할 수 있습니다. + // ImageResponse의 너비와 높이도 설정할 수 있습니다. ...size, } ) @@ -196,7 +196,7 @@ export default function Icon({ params }) { } ``` -| 경로 | URL | `params` | +| 경로 | URL | `params` | | ------------------------------- | ----------- | ------------------------- | | `app/shop/icon.js` | `/shop` | `undefined` | | `app/shop/[slug]/icon.js` | `/shop/1` | `{ slug: '1' }` | @@ -213,9 +213,9 @@ default export 함수는 `Blob` | `ArrayBuffer` | `TypedArray` | `DataView` | `R `icon` 또는 `apple-icon` 경로에서 `size`와 `contentType` 변수를 export 하여 아이콘의 메타 데이터를 선택적으로 설정할 수 있습니다. -| 옵션 | 타입 | -| ----------------------------- | --------------------------------------------------------------------------------------------------------------------- | -| [`size`](#size) | `{ width: number; height: number }` | +| 옵션 | 타입 | +| ----------------------------- | ------------------------------------------------------------------------------------------------------- | +| [`size`](#size) | `{ width: number; height: number }` | | [`contentType`](#contenttype) | `string` - [이미지 MIME 타입](https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/MIME_types) | #### `size` @@ -258,7 +258,7 @@ export default function Icon() {} `icon` 및 `apple-icon`은 Pages 및 Layouts와 동일한 [경로 세그먼트 설정](/docs/app/api-reference/file-conventions/route-segment-config) 옵션을 사용할 수 있는 특수한 [경로 핸들러](/docs/app/building-your-application/routing/router-handlers)입니다. -| 옵션 | 타입 | 기본값 | +| 옵션 | 타입 | 기본값 | | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ---------- | | [`dynamic`](/docs/app/api-reference/file-conventions/route-segment-config#dynamic) | `'auto' \| 'force-dynamic' \| 'error' \| 'force-static'` | `'auto'` | | [`revalidate`](/docs/app/api-reference/file-conventions/route-segment-config#revalidate) | `false \| 'force-cache' \| 0 \| number` | `false` | @@ -279,6 +279,6 @@ export default function Icon() {} ## 버전 히스토리 -| 버전 | 변경 사항 | -| --------- | -------------------------------------------- | +| 버전 | 변경 사항 | +| --------- | ---------------------------------- | | `v13.3.0` | `favicon` `icon` `apple-icon` 도입 | diff --git a/docs/03-pages/01-building-your-application/04-styling/03-css-in-js.mdx b/docs/03-pages/01-building-your-application/04-styling/03-css-in-js.mdx index 92956ddb4..65f820f1f 100644 --- a/docs/03-pages/01-building-your-application/04-styling/03-css-in-js.mdx +++ b/docs/03-pages/01-building-your-application/04-styling/03-css-in-js.mdx @@ -5,15 +5,24 @@ source: app/building-your-application/styling/css-in-js ---
- 예시- [Styled JSX](https://github.com/vercel/next.js/tree/canary/examples/with-styled-jsx) - - [Styled Components](https://github.com/vercel/next.js/tree/canary/examples/with-styled-components) - - [Emotion](https://github.com/vercel/next.js/tree/canary/examples/with-emotion) - - [Linaria](https://github.com/vercel/next.js/tree/canary/examples/with-linaria) - - [Tailwind CSS + Emotion](https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss-emotion) - - [Styletron](https://github.com/vercel/next.js/tree/canary/examples/with-styletron) - - [Cxs](https://github.com/vercel/next.js/tree/canary/examples/with-cxs) - [Aphrodite](https://github.com/vercel/next.js/tree/canary/examples/with-aphrodite) - - [Fela](https://github.com/vercel/next.js/tree/canary/examples/with-aphrodite) - - [Stitches](https://github.com/vercel/next.js/tree/canary/examples/with-stitches) + 예시- [Styled + JSX](https://github.com/vercel/next.js/tree/canary/examples/with-styled-jsx) - + [Styled + Components](https://github.com/vercel/next.js/tree/canary/examples/with-styled-components) + - + [Emotion](https://github.com/vercel/next.js/tree/canary/examples/with-emotion) + - + [Linaria](https://github.com/vercel/next.js/tree/canary/examples/with-linaria) + - [Tailwind CSS + + Emotion](https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss-emotion) + - + [Styletron](https://github.com/vercel/next.js/tree/canary/examples/with-styletron) + - [Cxs](https://github.com/vercel/next.js/tree/canary/examples/with-cxs) - + [Aphrodite](https://github.com/vercel/next.js/tree/canary/examples/with-aphrodite) + - + [Fela](https://github.com/vercel/next.js/tree/canary/examples/with-aphrodite) + - + [Stitches](https://github.com/vercel/next.js/tree/canary/examples/with-stitches)
Next.js에서 기존의 CSS-in-JS를 사용할 수 있습니다. 가장 간단한 방법은 인라인 스타일입니다. diff --git a/docs/03-pages/01-building-your-application/05-optimizing/06-lazy-loading.mdx b/docs/03-pages/01-building-your-application/05-optimizing/06-lazy-loading.mdx index 9026f6592..8b890b49d 100644 --- a/docs/03-pages/01-building-your-application/05-optimizing/06-lazy-loading.mdx +++ b/docs/03-pages/01-building-your-application/05-optimizing/06-lazy-loading.mdx @@ -2,4 +2,4 @@ title: Lazy Loading description: 불러온 라이브러리와 React 컴포넌트를 Lazy load해서 애플리케이션의 로드 성능을 향상시킵니다. source: app/building-your-application/optimizing/lazy-loading ---- \ No newline at end of file +--- diff --git a/docs/03-pages/01-building-your-application/06-configuring/12-error-handling.mdx b/docs/03-pages/01-building-your-application/06-configuring/12-error-handling.mdx index 27df5488c..5fd5ed30d 100644 --- a/docs/03-pages/01-building-your-application/06-configuring/12-error-handling.mdx +++ b/docs/03-pages/01-building-your-application/06-configuring/12-error-handling.mdx @@ -100,4 +100,4 @@ export default MyApp ### Reporting Errors -클라이언트 오류를 모니터링하려면 [Sentry](https://github.com/vercel/next.js/tree/canary/examples/with-sentry), Bugsnag 또는 Datadog과 같은 서비스를 사용하세요. \ No newline at end of file +클라이언트 오류를 모니터링하려면 [Sentry](https://github.com/vercel/next.js/tree/canary/examples/with-sentry), Bugsnag 또는 Datadog과 같은 서비스를 사용하세요. diff --git a/examples/blog-starter/components/alert.tsx b/examples/blog-starter/components/alert.tsx index 067672f38..dcd1f2bca 100644 --- a/examples/blog-starter/components/alert.tsx +++ b/examples/blog-starter/components/alert.tsx @@ -10,8 +10,8 @@ const Alert = ({ preview }: Props) => { return (
@@ -21,7 +21,7 @@ const Alert = ({ preview }: Props) => { This page is a preview.{' '} Click here {' '} @@ -32,7 +32,7 @@ const Alert = ({ preview }: Props) => { The source code for this blog is{' '} available on GitHub diff --git a/examples/blog-starter/components/avatar.tsx b/examples/blog-starter/components/avatar.tsx index 920d38516..f82292ba5 100644 --- a/examples/blog-starter/components/avatar.tsx +++ b/examples/blog-starter/components/avatar.tsx @@ -6,7 +6,7 @@ type Props = { const Avatar = ({ name, picture }: Props) => { return (
- {name} + {name}
{name}
) diff --git a/examples/blog-starter/components/cover-image.tsx b/examples/blog-starter/components/cover-image.tsx index 4c200c5b7..b1949f6b9 100644 --- a/examples/blog-starter/components/cover-image.tsx +++ b/examples/blog-starter/components/cover-image.tsx @@ -13,8 +13,8 @@ const CoverImage = ({ title, src, slug }: Props) => { {`Cover { return ( -