
최근에 Next.js 최신 버전을 이용해서 프로젝트를 시작했다 (겁도 없이)
얼마 전 <title> 같은 중요한 태그가 <body> 안에 들어있으니 빨리 수정해달라는 요청을 받았다
음? 분명히 Next.js가 <head> 안에 알아서 잘 넣어준다고 했는데
이때까지만 해도 말도 안 되는 소리라고 생각했다
그런데 설마 하는 생각으로 개발자 도구를 열어보니 진짜 <body> 안에 있었다 🫢
(참고용 사진)

<body> 안에 있으면 안 되는 태그들이기 때문에 혼란스러워지기 시작했다
말도 안 된다는 생각에 구글링을 하기 시작했다.
"next.js 메타데이터가 body안에"
...
아무리 검색해 봐도 내가 원하던 내용을 찾지 못했다
그래서 GPT, Claude에게도 정성스럽게 질문을 했지만
결국 어느 곳에서도 원하는 답을 들을 수 없었다
그러면 도대체 왜 <body>태그 안에 메타데이터가 들어갔을까?
Next.js 공식문서를 보기 시작했다
Streaming metadata
공식 문서를 보던 중 드디어 이거 때문인가? 싶은 내용을 찾았다

Metadata returned by generateMetadata is streamed to the client. This allows Next.js to inject metadata into the HTML as soon as it's resolved.
Since page metadata primarily targets bots and crawlers, Next.js will stream metadata for bots that can execute JavaScript and inspect the full page DOM (e.g. Googlebot). However, metadata will continue blocking the render of the page for HTML-limited bots (e.g. Twitterbot) as these cannot execute JavaScript while crawling.
Next.js automatically detects the user agent of incoming requests to determine whether to serve streaming metadata or fallback to blocking metadata.
If you need to customize this list, you can define them manually using the htmlLimitedBots option in next.config.js. Next.js will ensure user agents matching this regex receive blocking metadata when requesting your web page.
(원문 - https://nextjs.org/docs/app/api-reference/functions/generate-metadata#streaming-metadata)
공식 문서를 읽고 내가 이해한 대로 요약해 보면 다음과 같다
15.2.0 이전 버전의 generateMetadata는 동적 데이터를 가져오거나 비동기 작업을 수행해야 하는 경우 메타데이터 생성이 끝나야 초기 UI를 전송할 수 있었다. 그래서 사용자에게 시각적으로 보이는 내용이 지연되는 문제가 발생했다
15.2.0부터는 generateMetadata가 완료되기 전에도 초기 UI를 브라우저로 전송할 수 있도록 하여 이 문제를 개선했고 이게 Streaming metadata이다
그래서 예상을 해보자면 초기 UI가 준비되었을 때 메타데이터는 아직 준비가 되지 않았었고
초기 UI를 먼저 그린 다음에 메타데이터가 준비되면 body에 배치한 것이다
실제로 15.2.0 버전 이전으로 다운그레이드 해보면 이 문제가 바로 해결된다
내가 이해한 대로 요약해 보면 다음과 같다
Next.js에서 메타데이터가 완전히 생성되기 전에는 크롤러가 읽을 수 없게 제한한다.
크롤러가 읽을 때는 정상적으로 <head>태그에 들어간 HTML을 보게 된다
실제로 이렇게 동작하게 되면 초기 렌더링 속도도 빨라지고 SEO까지 손해 보지 않는 완벽한 업데이트이다
아직 풀리지 않은 궁금증
1. 정적 메타데이터로 선언했을 때에도 <body>태그에 배치되는 이유는?
2. 초기 UI를 먼저 그린 다음에 메타데이터 생성이 끝나고 <head>에 배치하는 것은 안되는 것인가?
아직 모든 궁금증이 해결되지 않아서 더 공부해 봐야 될 것 같다