Skip to content

Conversation

@sauhardh
Copy link

@sauhardh sauhardh commented Nov 1, 2025

Priority: LOW

Description

  • Replaces regular script tag with Script from next/script
  • strategy="afterInteractive" should behave as async defer attirbute
  • line wrapping, and other nits are auto.

next/script docs: https://nextjs.org/docs/pages/api-reference/components/script

This resolves the warning of Do not add <script> tags using next/head.

Resolves #4517

Summary by CodeRabbit

  • Chores
    • Updated script loading mechanism to use framework-optimized approaches for improved performance.
    • Applied consistent code formatting across components.

@netlify
Copy link

netlify bot commented Nov 1, 2025

Deploy Preview for asyncapi-website ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 362771e
🔍 Latest deploy log https://app.netlify.com/projects/asyncapi-website/deploys/6905f1872aa3d6000845b7a1
😎 Deploy Preview https://deploy-preview-4523--asyncapi-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@asyncapi-bot
Copy link
Contributor

asyncapi-bot commented Nov 1, 2025

We require all PRs to follow Conventional Commits specification.
More details 👇🏼

 Unknown release type "Fix" found in pull request title "Fix: Hydration warning on local development". 

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Welcome to AsyncAPI. Thanks a lot for creating your first pull request. Please check out our contributors guide useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 1, 2025

Walkthrough

The PR resolves Next.js hydration errors by replacing inline <script> tags in application pages with Next.js Script components from next/script using the afterInteractive strategy. Additional changes include updating next-env.d.ts with type reference directives and standardizing quote formatting across JSX attributes.

Changes

Cohort / File(s) Summary
TypeScript Configuration
next-env.d.ts
Adds type reference directives for Next.js types, image types, and route declarations; includes note that file should not be edited.
Script Component Migration
pages/_app.tsx, pages/_document.tsx
Replaces static <script> tags in Head with Next.js Script components using strategy="afterInteractive" to load external scripts; standardizes JSX attribute quoting to double quotes for consistency.

Sequence Diagram

sequenceDiagram
    participant Browser
    participant OldFlow as Old: Static Script Tag
    participant NewFlow as New: Next.js Script Component
    participant ExternalScript as External JS

    rect rgb(220, 240, 220)
    Note over OldFlow: Hydration Mismatch Risk
    Browser->>OldFlow: Initial Page Load
    OldFlow->>ExternalScript: Load immediately (timing unclear)
    ExternalScript-->>Browser: Script Applied
    Note over Browser: ⚠️ SSR/Client mismatch possible
    end

    rect rgb(240, 220, 220)
    Note over NewFlow: Optimized Loading
    Browser->>NewFlow: Initial Page Load
    Note over NewFlow: Defer to afterInteractive phase
    Browser->>NewFlow: Page interactive + hydration complete
    NewFlow->>ExternalScript: Load after interaction
    ExternalScript-->>Browser: Script Applied
    Note over Browser: ✓ Safe hydration
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Consistent pattern: the Script component migration follows the same structure across both files
  • Changes are largely homogeneous (script tag replacement + quote normalization)
  • Minor formatting adjustments without complex logic
  • Consider: verify that strategy="afterInteractive" is the correct choice for each script's use case (GitHub buttons and analytics patterns)

Poem

🐰 The hydration hops away,
Scripts now load the Next.js way,
With afterInteractive care,
No more errors in the air!
SSR and client shake hands,
As harmony across the lands!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The PR includes changes that extend beyond the specific requirements of issue #4517. While the core script replacement fix is properly scoped, the changeset includes quote formatting unification (converting single quotes to double quotes) and additions to next-env.d.ts with type reference directives that are not directly required to fix the hydration warning. The PR description acknowledges these as "formatting nits" applied automatically, suggesting they were intentionally included, but they technically fall outside the scope of the linked issue which specifically focuses on replacing script tags to resolve the hydration warning. Consider separating the formatting and TypeScript configuration changes into a dedicated PR focused on code style improvements. This would keep the hydration warning fix PR narrowly scoped and easier to review. Alternatively, if these changes are considered essential supporting improvements, document them as intentional in the PR description to clarify scope for future reviewers.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Fix: Hydration warning on local development" is fully related to the main change in the pull request. The title clearly summarizes the primary objective: fixing the hydration warning that occurs during local development. The changes in pages/_app.tsx and pages/_document.tsx directly implement this fix by replacing HTML script tags with Next.js Script components using the afterInteractive strategy, which is the exact solution described in the linked issue #4517. The title is concise, specific, and accurately reflects the core purpose of the changeset.
Linked Issues Check ✅ Passed The PR successfully addresses the core requirements from issue #4517. The script tags have been replaced with Next.js Script components in both pages/_app.tsx and pages/_document.tsx using strategy="afterInteractive" to mirror the async defer behavior. This implementation directly resolves the "Do not add <script> tags using next/head" hydration warning reported in the issue. The changes align with the diagnostic suggestion provided by Next.js and fulfill the objective of optimizing script loading behavior as mentioned in the issue.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@asyncapi-bot
Copy link
Contributor

⚡️ Lighthouse report for the changes in this PR:

Category Score
🔴 Performance 45
🟢 Accessibility 98
🟢 Best practices 92
🟢 SEO 100
🔴 PWA 33

Lighthouse ran on https://deploy-preview-4523--asyncapi-website.netlify.app/

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 053e5a6 and 362771e.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • next-env.d.ts (1 hunks)
  • pages/_app.tsx (2 hunks)
  • pages/_document.tsx (2 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: anshgoyalevil
Repo: asyncapi/website PR: 3950
File: scripts/utils/check-locales.ts:122-129
Timestamp: 2025-04-20T16:05:16.482Z
Learning: In the AsyncAPI website project, Next.js throws errors at runtime when locale files are missing, making additional validation for missing files unnecessary in the check-locales script.
Learnt from: akshatnema
Repo: asyncapi/website PR: 3378
File: scripts/markdown/check-markdown.js:1-1
Timestamp: 2024-11-25T18:34:51.303Z
Learning: When reviewing `scripts/markdown/check-markdown.js`, optimizations should be addressed in separate issues and not included in the current pull request.
Learnt from: akshatnema
Repo: asyncapi/website PR: 3262
File: components/newsroom/FeaturedBlogPost.tsx:90-92
Timestamp: 2024-10-11T07:38:35.745Z
Learning: In Next.js, nested `<a>` tags cause hydration issues due to invalid HTML. To fix this, avoid nesting `<a>` tags by replacing inner `<a>` tags with non-interactive elements like `<span>`, and use click handlers to maintain interactivity if needed.
Learnt from: akshatnema
Repo: asyncapi/website PR: 3262
File: components/Avatar.tsx:35-44
Timestamp: 2024-10-11T10:46:58.882Z
Learning: In Next.js, when avoiding nested `<a>` tags due to hydration issues, use accessible non-link elements like `<button>` or `<span>` with appropriate roles, `tabIndex`, and event handlers to maintain accessibility and SEO.
📚 Learning: 2025-01-18T08:44:43.614Z
Learnt from: akshatnema
Repo: asyncapi/website PR: 3423
File: tests/index.test.js:2-7
Timestamp: 2025-01-18T08:44:43.614Z
Learning: In the AsyncAPI website project, JavaScript test files must include the .ts extension when importing TypeScript files (e.g., `require('../scripts/build-rss.ts')`). This is enforced by the project's configuration which uses `moduleResolution: "bundler"` in tsconfig.json and TypeScript-aware ESLint plugins. The .ts extensions are required even though the files are imported using CommonJS require statements.

Applied to files:

  • next-env.d.ts
📚 Learning: 2025-04-20T16:05:16.482Z
Learnt from: anshgoyalevil
Repo: asyncapi/website PR: 3950
File: scripts/utils/check-locales.ts:122-129
Timestamp: 2025-04-20T16:05:16.482Z
Learning: In the AsyncAPI website project, Next.js throws errors at runtime when locale files are missing, making additional validation for missing files unnecessary in the check-locales script.

Applied to files:

  • next-env.d.ts
  • pages/_app.tsx
  • pages/_document.tsx
📚 Learning: 2025-01-18T08:44:43.614Z
Learnt from: akshatnema
Repo: asyncapi/website PR: 3423
File: tests/index.test.js:2-7
Timestamp: 2025-01-18T08:44:43.614Z
Learning: In the AsyncAPI website project, JavaScript test files must include the .ts extension when importing TypeScript files (e.g., `require('../scripts/build-rss.ts')`). This is a project-specific requirement enforced by the linting rules and build setup, even though it differs from typical Node.js behavior.

Applied to files:

  • next-env.d.ts
📚 Learning: 2024-10-11T07:38:35.745Z
Learnt from: akshatnema
Repo: asyncapi/website PR: 3262
File: components/newsroom/FeaturedBlogPost.tsx:90-92
Timestamp: 2024-10-11T07:38:35.745Z
Learning: In Next.js, nested `<a>` tags cause hydration issues due to invalid HTML. To fix this, avoid nesting `<a>` tags by replacing inner `<a>` tags with non-interactive elements like `<span>`, and use click handlers to maintain interactivity if needed.

Applied to files:

  • pages/_app.tsx
  • pages/_document.tsx
📚 Learning: 2024-10-11T10:46:58.882Z
Learnt from: akshatnema
Repo: asyncapi/website PR: 3262
File: components/Avatar.tsx:35-44
Timestamp: 2024-10-11T10:46:58.882Z
Learning: In Next.js, when avoiding nested `<a>` tags due to hydration issues, use accessible non-link elements like `<button>` or `<span>` with appropriate roles, `tabIndex`, and event handlers to maintain accessibility and SEO.

Applied to files:

  • pages/_app.tsx
  • pages/_document.tsx
📚 Learning: 2024-11-11T21:30:32.478Z
Learnt from: amanbhoria
Repo: asyncapi/website PR: 3373
File: components/AlgoliaSearch.tsx:313-313
Timestamp: 2024-11-11T21:30:32.478Z
Learning: In the `SearchButton` component within `components/AlgoliaSearch.tsx`, if the component re-renders on every button click and the `useEffect` runs accordingly, adding dependencies to the dependency array might not be necessary.

Applied to files:

  • pages/_app.tsx
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Lighthouse CI
🔇 Additional comments (4)
pages/_document.tsx (2)

5-5: Import looks good.

The Script import from next/script is correctly added to support the Script component usage below.


56-59: Remove duplicate Script component and move out of Head.

The Script component is incorrectly placed inside <Head> (lines 56-59). Next.js Script components must be placed outside <Head> to function correctly and will otherwise be ignored or cause errors. Additionally, https://buttons.github.io/buttons.js is already loaded in pages/_app.tsx at line 27, creating duplicate loading. Remove this Script from _document.tsx or consolidate to a single location outside the <Head> component.

⛔ Skipped due to learnings
Learnt from: akshatnema
Repo: asyncapi/website PR: 3378
File: scripts/markdown/check-markdown.js:1-1
Timestamp: 2024-11-25T18:34:51.303Z
Learning: When reviewing `scripts/markdown/check-markdown.js`, optimizations should be addressed in separate issues and not included in the current pull request.
Learnt from: anshgoyalevil
Repo: asyncapi/website PR: 3950
File: scripts/utils/check-locales.ts:122-129
Timestamp: 2025-04-20T16:05:16.482Z
Learning: In the AsyncAPI website project, Next.js throws errors at runtime when locale files are missing, making additional validation for missing files unnecessary in the check-locales script.
Learnt from: anshgoyalevil
Repo: asyncapi/website PR: 3301
File: scripts/markdown/check-markdown.js:0-0
Timestamp: 2024-10-18T17:24:45.053Z
Learning: In `scripts/markdown/check-markdown.js`, the script is not run in an asynchronous environment, so refactoring it to use `async/await` is unnecessary.
Learnt from: akshatnema
Repo: asyncapi/website PR: 3262
File: components/newsroom/FeaturedBlogPost.tsx:90-92
Timestamp: 2024-10-11T07:38:35.745Z
Learning: In Next.js, nested `<a>` tags cause hydration issues due to invalid HTML. To fix this, avoid nesting `<a>` tags by replacing inner `<a>` tags with non-interactive elements like `<span>`, and use click handlers to maintain interactivity if needed.
Learnt from: akshatnema
Repo: asyncapi/website PR: 3262
File: components/Avatar.tsx:35-44
Timestamp: 2024-10-11T10:46:58.882Z
Learning: In Next.js, when avoiding nested `<a>` tags due to hydration issues, use accessible non-link elements like `<button>` or `<span>` with appropriate roles, `tabIndex`, and event handlers to maintain accessibility and SEO.
next-env.d.ts (1)

1-6: Standard Next.js TypeScript configuration file.

This is the standard auto-generated Next.js environment declaration file with appropriate type references for Next.js core types, image types, and route types. The file structure and content are correct.

pages/_app.tsx (1)

16-16: Import looks good.

The Script import from next/script is correctly added.

Comment on lines +25 to +28
<Script
strategy="afterInteractive"
src="https://buttons.github.io/buttons.js"
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Duplicate script loading and incorrect placement.

Same issues as in pages/_document.tsx:

  1. Script in Head: The Script component should not be inside <Head>. Place it in the component body instead.

  2. Duplicate loading: This script is already loaded in pages/_document.tsx at lines 56-59. Loading it in both files is redundant and inefficient.

Recommendation: Since this is an application-level script for GitHub buttons, consider:

  • Keeping it only in _app.tsx (remove from _document.tsx)
  • Moving it outside the <Head> component to the component body (e.g., place it before or after the <AlgoliaSearch> wrapper)

Apply this diff to fix the placement:

       {/* <MDXProvider components={mdxComponents}> */}
       <Head>
-        <Script
-          strategy="afterInteractive"
-          src="https://buttons.github.io/buttons.js"
-        />
       </Head>
+      <Script
+        strategy="afterInteractive"
+        src="https://buttons.github.io/buttons.js"
+      />
       <AlgoliaSearch>

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
pages/_app.tsx around lines 25-28: The GitHub buttons Script is incorrectly
placed inside Head and duplicates the same script loaded in pages/_document.tsx;
remove this Script from _app.tsx (or conversely remove it from _document.tsx) so
it only exists once in the app, and if you keep it in _app.tsx move the Script
component out of Head into the component body (e.g., just before or after the
<AlgoliaSearch> wrapper) using strategy="afterInteractive" and the same src.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Do not add <script> tags using next/head

2 participants