Skip to content
Open
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"dependencies": {
"@nuxt/devtools-kit": "^3.0.0",
"@nuxt/kit": "^4.1.2",
"consola": "^3.4.2",
"h3": "^1.15.4",
"knitwork": "^1.3.0",
"magic-string": "^0.30.19",
Expand Down
5 changes: 4 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions src/runtime/core/components/nuxt-island.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import NuxtIsland from '#app/components/nuxt-island'
import { useNuxtApp } from '#imports'
import { logger } from '../../logger'

const originalSetup = NuxtIsland.setup!
const HintsNuxtIsland = Object.assign(<typeof NuxtIsland>{}, NuxtIsland, <typeof NuxtIsland>{
setup(props, ctx) {
if (useNuxtApp().ssrContext?.islandContext) {
console.warn(
`[@nuxt/hints] Nesting islands within islands is not recommanded for performance reasons. This leads to waterfall calls.`,
logger.warn(
`Nesting islands within islands is not recommanded for performance reasons. This leads to waterfall calls.`,
)
}
return originalSetup(props, ctx)
Expand Down
3 changes: 2 additions & 1 deletion src/runtime/hydration/composables.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getCurrentInstance, onMounted } from 'vue'
import { useNuxtApp } from '#imports'
import { HYDRATION_ROUTE, formatHTML } from './utils'
import { logger } from '../logger'
import type { HydrationMismatchPayload } from './types'
/**
* prefer implementing onMismatch hook after vue 3.6
Expand Down Expand Up @@ -40,7 +41,7 @@ export function useHydrationCheck() {
method: 'POST',
body: payload,
})
console.warn(`[nuxt/hints:hydration] Component ${instance.type.name ?? instance.type.displayName ?? instance.type.__name ?? instance.type.__file} seems to have different html pre and post-hydration. Please make sure you don't have any hydration issue.`)
logger.warn(`[hydration] Component ${instance.type.name ?? instance.type.displayName ?? instance.type.__name ?? instance.type.__file} seems to have different html pre and post-hydration. Please make sure you don't have any hydration issue.`)
}
})
}
3 changes: 3 additions & 0 deletions src/runtime/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createConsola } from 'consola'

export const logger = createConsola().withTag('hints')
9 changes: 5 additions & 4 deletions src/runtime/third-party-scripts/plugin.client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { defineNuxtPlugin, ref, useNuxtApp } from '#imports'
import { logger } from '../logger'

const EXTENSIONS_SCHEMES_RE = /^(chrome-extension|moz-extension|safari-extension|ms-browser-extension):/

Expand Down Expand Up @@ -45,7 +46,7 @@ export default defineNuxtPlugin({
existingScript.loaded = true
}
else {
console.warn(`[@nuxt/hints]: Script loaded event received for a script not tracked: ${script.src}. Please open an issue with a minimal reproduction if you think this is a bug.`)
logger.warn(`Script loaded event received for a script not tracked: ${script.src}. Please open an issue with a minimal reproduction if you think this is a bug.`)
scripts.value.push({ element: script, loaded: true })
}
})
Expand All @@ -59,7 +60,7 @@ export default defineNuxtPlugin({
}
}
if (hasThirdPartyScript && !isUsingNuxtScripts) {
console.info('ℹ️ [@nuxt/hints]: Third-party scripts detected on page load: consider using @nuxt/scripts')
logger.info('Third-party scripts detected on page load: consider using @nuxt/scripts')
}
})

Expand All @@ -83,7 +84,7 @@ export default defineNuxtPlugin({

function onScriptAdded(script: HTMLScriptElement) {
if (!script.crossOrigin) {
console.warn(`[@nuxt/hints]: Third-party script "${script.src}" is missing crossorigin attribute. Consider adding crossorigin="anonymous" for better security and error reporting.`)
logger.warn(`Third-party script "${script.src}" is missing crossorigin attribute. Consider adding crossorigin="anonymous" for better security and error reporting.`)
}
nuxtApp.callHook('hints:scripts:added', script)
.then(() => {
Expand All @@ -100,7 +101,7 @@ export default defineNuxtPlugin({
}
})

console.info(`ℹ️ [@nuxt/hints]: Dynamically added third-party script detected: ${script.src}`)
logger.info(`Dynamically added third-party script detected: ${script.src}`)
}
},
})
Expand Down
49 changes: 25 additions & 24 deletions src/runtime/web-vitals/plugin.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { defineNuxtPlugin, useNuxtApp } from '#imports'
import { onINP, onLCP, onCLS } from 'web-vitals/attribution'
import { defu } from 'defu'
import { ref } from 'vue'
import { logger } from '../logger'

type ElementNode = ChildNode & { attributes: { href: { value: string } } }

Expand Down Expand Up @@ -46,8 +47,8 @@ export default defineNuxtPlugin({
if (metric.rating === 'good') {
return
}
console.info(
'[@nuxt/hints:web-vitals] INP Metric: ',
logger.info(
'[web-vitals] INP Metric: ',
metric,
)
nuxtApp.__hints.webvitals.inp.value.push(metric)
Expand All @@ -60,8 +61,8 @@ export default defineNuxtPlugin({
if (metric.rating === 'good') {
return
}
console.info(
`[@nuxt/hints:web-vitals] LCP Metric: `,
logger.info(
`[web-vitals] LCP Metric: `,
metric,
)
nuxtApp.__hints.webvitals.lcp.value.push(metric)
Expand All @@ -73,43 +74,43 @@ export default defineNuxtPlugin({
}

if (performanceEntry.element.attributes?.getNamedItem('loading')?.value === 'lazy') {
console.warn(
'[@nuxt/hints:performance] LCP Element should not have `loading="lazy"` \n\n Learn more: https://web.dev/optimize-lcp/#optimize-the-priority-the-resource-is-given',
logger.warn(
'[performance] LCP Element should not have `loading="lazy"` \n\n Learn more: https://web.dev/optimize-lcp/#optimize-the-priority-the-resource-is-given',
)
}
if (hasImageFormat(performanceEntry.element.src)) {
if (
!performanceEntry.element.src.includes('webp')
|| !performanceEntry.element.src.includes('avif')
) {
console.warn(
'[@nuxt/hints:performance] LCP Element can be served in a next gen format like `webp` or `avif` \n\n Learn more: https://web.dev/choose-the-right-image-format/ \n\n Use: https://image.nuxt.com/usage/nuxt-img#format',
logger.warn(
'[performance] LCP Element can be served in a next gen format like `webp` or `avif` \n\n Learn more: https://web.dev/choose-the-right-image-format/ \n\n Use: https://image.nuxt.com/usage/nuxt-img#format',
)
}
}
if (performanceEntry.element.fetchPriority !== 'high') {
console.warn(
'[@nuxt/hints:performance] LCP Element can have `fetchPriority="high"` to load as soon as possible \n\n Learn more: https://web.dev/optimize-lcp/#optimize-the-priority-the-resource-is-given',
logger.warn(
'[performance] LCP Element can have `fetchPriority="high"` to load as soon as possible \n\n Learn more: https://web.dev/optimize-lcp/#optimize-the-priority-the-resource-is-given',
)
}
if (
!performanceEntry.element.attributes.getNamedItem('height')
|| !performanceEntry.element.attributes.getNamedItem('width')
) {
console.warn(
'[@nuxt/hints:performance] Images should have `width` and `height` sizes set \n\n Learn more: https://web.dev/optimize-cls/#images-without-dimensions \n\n Use: https://image.nuxt.com/usage/nuxt-img#width-height',
logger.warn(
'[performance] Images should have `width` and `height` sizes set \n\n Learn more: https://web.dev/optimize-cls/#images-without-dimensions \n\n Use: https://image.nuxt.com/usage/nuxt-img#width-height',
)
}
if (performanceEntry.startTime > 2500) {
console.warn(
`[@nuxt/hints:performance] LCP Element loaded in ${performanceEntry.startTime} miliseconds. Good result is below 2500 miliseconds \n\n Learn more: https://web.dev/lcp/#what-is-a-good-lcp-score`,
logger.warn(
`[performance] LCP Element loaded in ${performanceEntry.startTime} miliseconds. Good result is below 2500 miliseconds \n\n Learn more: https://web.dev/lcp/#what-is-a-good-lcp-score`,
)
}

if (!isElementPreloaded(performanceEntry.element.src)) {
console.warn(
logger.warn(

'[@nuxt/hints:performance] LCP Element can be preloaded in `head` to improve load time \n\n Learn more: https://web.dev/optimize-lcp/#optimize-when-the-resource-is-discovered \n\n Use: https://image.nuxt.com/usage/nuxt-img#preload',
'[performance] LCP Element can be preloaded in `head` to improve load time \n\n Learn more: https://web.dev/optimize-lcp/#optimize-when-the-resource-is-discovered \n\n Use: https://image.nuxt.com/usage/nuxt-img#preload',
)
}
}
Expand All @@ -121,8 +122,8 @@ export default defineNuxtPlugin({
if (metric.rating === 'good') {
return
}
console.info(
'[@nuxt/hints:web-vitals] CLS Metric: ', metric,
logger.info(
'[web-vitals] CLS Metric: ', metric,
)
nuxtApp.callHook(
'hints:webvitals:cls',
Expand All @@ -141,14 +142,14 @@ export default defineNuxtPlugin({
// Nuxt DevTools button causes small layout shift so we ignore it
if (!sourceElement || sourceElement.parentElement?.className.includes('nuxt-devtools')) return

console.info(
'[@nuxt/hints:performance] Potential CLS Element: ',
logger.info(
'[performance] Potential CLS Element: ',
sourceElement,
)

if ((performanceEntry.value ?? 0) > 0.1) {
console.warn(
`[@nuxt/hints:performance] CLS was ${performanceEntry.value}. Good result is below 0.1 \n\n Learn more: https://web.dev/articles/cls#what-is-a-good-cls-score`,
logger.warn(
`[performance] CLS was ${performanceEntry.value}. Good result is below 0.1 \n\n Learn more: https://web.dev/articles/cls#what-is-a-good-cls-score`,
)
}

Expand All @@ -157,8 +158,8 @@ export default defineNuxtPlugin({
&& (!sourceElement.attributes.getNamedItem('height')
|| !sourceElement.attributes.getNamedItem('width'))
) {
console.warn(
'[@nuxt/hints:performance] Images should have `width` and `height` sizes set \n\n Learn more: https://web.dev/optimize-cls/#images-without-dimensions \n\n Use: https://image.nuxt.com/usage/nuxt-img#width-height',
logger.warn(
'[performance] Images should have `width` and `height` sizes set \n\n Learn more: https://web.dev/optimize-cls/#images-without-dimensions \n\n Use: https://image.nuxt.com/usage/nuxt-img#width-height',
)
}
}
Expand Down
Loading