Skip to content

Conversation

@11Alone11
Copy link
Contributor

@11Alone11 11Alone11 commented Sep 11, 2025

🔗 Linked issue

resolves #33210

📚 Description

Fixes a bug in the Nuxt loading indicator where backgroundSize could become Infinity when progress.value was 0.

Before:

backgroundSize: `${(100 / progress.value) * 100}% auto`,

After:

backgroundSize: `${
  progress.value > 0 ? (100 / progress.value) * 100 : 0
}% auto`,

@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Sep 11, 2025

Open in StackBlitz

@nuxt/kit

npm i https://pkg.pr.new/@nuxt/kit@33211

nuxt

npm i https://pkg.pr.new/nuxt@33211

@nuxt/rspack-builder

npm i https://pkg.pr.new/@nuxt/rspack-builder@33211

@nuxt/schema

npm i https://pkg.pr.new/@nuxt/schema@33211

@nuxt/vite-builder

npm i https://pkg.pr.new/@nuxt/vite-builder@33211

@nuxt/webpack-builder

npm i https://pkg.pr.new/@nuxt/webpack-builder@33211

commit: d7e618a

@coderabbitai
Copy link

coderabbitai bot commented Sep 11, 2025

Walkthrough

A single file, packages/nuxt/src/app/components/nuxt-loading-indicator.ts, was changed. The only functional edit adds a guard when computing backgroundSize: it uses (100 / progress.value) * 100 only if progress.value > 0, otherwise sets backgroundSize to 0 to avoid division by zero/Infinity. All other style properties and the component's public API, exports and vnode/slot structure remain unchanged. Edits elsewhere in the file are formatting and annotations.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Pre-merge checks (5 passed)

✅ Passed checks (5 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly and concisely summarises the primary change: it states a Nuxt bug fix that prevents an Infinity backgroundSize in the loading indicator, which directly matches the changeset. It is specific, focused, and readable for teammates scanning history.
Linked Issues Check ✅ Passed The change implements a defensive guard against division by zero when computing backgroundSize, which directly addresses the linked issue's objective of preventing "background-size: Infinity% auto" in SSR output; the modification is minimal and does not alter public APIs.
Out of Scope Changes Check ✅ Passed Based on the provided summary, the PR only changes the backgroundSize calculation in packages/nuxt/src/app/components/nuxt-loading-indicator.ts and does not introduce unrelated file or feature changes, so no out-of-scope modifications are evident.
Description Check ✅ Passed The description references the linked issue and includes clear before/after code snippets explaining the exact change to backgroundSize, so it is directly related to the changeset and the bug being fixed.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9c63214 and d7e618a.

📒 Files selected for processing (1)
  • packages/nuxt/src/app/components/nuxt-loading-indicator.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/nuxt/src/app/components/nuxt-loading-indicator.ts
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • 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.

Copy link

@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

🧹 Nitpick comments (3)
packages/nuxt/src/app/components/nuxt-loading-indicator.ts (3)

37-40: Type props with PropType instead of Function cast.

Avoids unsafe casts and improves DX.

-    estimatedProgress: {
-      type: Function as unknown as () => (
-        duration: number,
-        elapsed: number
-      ) => number,
+    estimatedProgress: {
+      type: Function as PropType<(duration: number, elapsed: number) => number>,
       required: false,
     },

Add this import:

import type { PropType } from 'vue'

77-80: Guard against boolean true leaking into CSS background.

If color is true, props.color || undefined can pass a truthy non-string. Coerce to string or omit.

-            background: error.value
-              ? props.errorColor
-              : props.color || undefined,
+            background: error.value
+              ? props.errorColor
+              : (typeof props.color === 'string' ? props.color : undefined),

85-85: Micro-optimisation: hint paint pipeline.

Add will-change to smooth animations on some browsers.

             transition: 'transform 0.1s, height 0.4s, opacity 0.4s',
+            willChange: 'transform, opacity',
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 327ba8f and 9c63214.

📒 Files selected for processing (1)
  • packages/nuxt/src/app/components/nuxt-loading-indicator.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Follow standard TypeScript conventions and best practices

Files:

  • packages/nuxt/src/app/components/nuxt-loading-indicator.ts
🧬 Code graph analysis (1)
packages/nuxt/src/app/components/nuxt-loading-indicator.ts (1)
packages/nuxt/src/app/composables/loading-indicator.ts (1)
  • useLoadingIndicator (170-188)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
  • GitHub Check: test-fixtures (windows-latest, built, vite, default, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (windows-latest, dev, vite, default, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, built, rspack, default, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (windows-latest, built, webpack, async, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, built, webpack, default, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (windows-latest, built, vite, async, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, built, rspack, async, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, built, webpack, async, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-on, js, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, default, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, async, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, default, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, default, manifest-off, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-off, json, lts/-1)
  • GitHub Check: test-size
  • GitHub Check: typecheck (ubuntu-latest, bundler)
  • GitHub Check: typecheck (windows-latest, bundler)
  • GitHub Check: test-benchmark
  • GitHub Check: code
🔇 Additional comments (4)
packages/nuxt/src/app/components/nuxt-loading-indicator.ts (4)

29-30: Readable default gradient — LGTM.

Pure formatting; improves readability without behaviour change.


45-52: Options passthrough — LGTM.

The composable receives the correct props; no behaviour change.


55-60: Expose shape — LGTM.

Public surface matches the composable API.


80-82: Division-by-zero guard — LGTM.

Prevents Infinity% CSS at 0 progress as intended.

backgroundSize: `${
progress.value > 0 ? (100 / progress.value) * 100 : 0
}% auto`,
transform: `scaleX(${progress.value}%)`,
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix transform: scaleX expects a unitless factor, not a percentage.

Using % yields invalid CSS. Also clamp and handle non-finite values.

-            transform: `scaleX(${progress.value}%)`,
+            transform: `scaleX(${Number.isFinite(progress.value) ? Math.max(0, Math.min(1, progress.value / 100)) : 0})`,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
transform: `scaleX(${progress.value}%)`,
transform: `scaleX(${Number.isFinite(progress.value) ? Math.max(0, Math.min(1, progress.value / 100)) : 0})`,
🤖 Prompt for AI Agents
In packages/nuxt/src/app/components/nuxt-loading-indicator.ts around line 83,
the transform uses `scaleX(${progress.value}%)` which is invalid because scaleX
expects a unitless factor; clamp progress to a finite number between 0 and 1
(e.g. coerce with Number(), handle NaN/Infinity to 0, then use
Math.min(Math.max(value, 0), 1)) and use that clamped value directly in the
scaleX() call without a '%' sign so the style becomes `transform:
\`scaleX(${clamped})\``.

@codspeed-hq
Copy link

codspeed-hq bot commented Sep 11, 2025

CodSpeed Performance Report

Merging #33211 will not alter performance

Comparing 11Alone11:fix-loading-indicator (d7e618a) with main (327ba8f)

Summary

✅ 10 untouched

@11Alone11 11Alone11 changed the title fix(loading-indicator): prevent backgroundSize Infinity value fix(nuxt): prevent backgroundSize Infinity value Sep 11, 2025
@11Alone11 11Alone11 changed the title fix(nuxt): prevent backgroundSize Infinity value fix(nuxt): prevent Infinity backgroundSize in loading indicator Sep 11, 2025
@11Alone11
Copy link
Contributor Author

@danielroe
As far as I can tell, the backgroundSize property is initially set during SSR, but disappears on the client after hydration because the background shorthand (color or gradient) overrides it.
In my view, it’s not entirely clear what purpose this property serves in practice, since it doesn’t seem to have an effect on the client.
This also makes it difficult to write a meaningful test for it.

@danielroe
Copy link
Member

danielroe commented Sep 11, 2025

interesting point. maybe we can revisit the attributes returned in this render function? CodeRabbit also noticed a valid issue with scaleX (which doesn't accept a percentage!)

@11Alone11
Copy link
Contributor Author

According to CSS Transforms Level 2, scaleX() can take either a <number> or a <percentage>.
However, percentages in this context are just another way of expressing numbers:

  • scaleX(100%) = scaleX(1)
  • scaleX(200%) = scaleX(2)
  • scaleX(50%) = scaleX(0.5)

So our current code using ${progress.value}% works, but it may be clearer (and more widely supported, since Level 2 is newer) to use a plain number instead, e.g. progress.value / 100.

https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scaleX

@danielroe danielroe merged commit be49123 into nuxt:main Sep 11, 2025
45 of 46 checks passed
@github-actions github-actions bot mentioned this pull request Sep 11, 2025
@github-actions github-actions bot mentioned this pull request Sep 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

<NuxtLoadingIndicator> renders inline styles with background-size: Infinity% auto (invalid CSS)

2 participants