Install nuxt-viewport
mainTo add nuxt-viewport to your Nuxt 3 or Nuxt Bridge project, use the Nuxt module installer:
npx nuxi@latest module add nuxt-viewportrepository·main·Indexed 41 days ago
https://github.com/mvrlin/nuxt-viewportA Nuxt module for defining and managing custom viewports and breakpoints in Nuxt 3 or Nuxt Bridge projects. It utilizes the MatchMedia API and automatic device detection via Cookies and User-Agents to prevent layout shifts. Features include the useViewport() composable, a ViewportManager API for breakpoint comparisons (e.g., isLessThan, isGreaterThan), and the ability to override global viewport settings per page using definePageMeta.
To add nuxt-viewport to your Nuxt 3 or Nuxt Bridge project, use the Nuxt module installer:
npx nuxi@latest module add nuxt-viewportYou can override global viewport settings for specific routes using definePageMeta within your Vue component.
<script setup>
definePageMeta({
viewport: {
breakpoints: {
desktop: 1024,
mobile: 320,
tablet: 768
},
cookie: {
name: 'viewport-per-page'
}
// Other fields will be inherited from the global configuration
}
})
</script>You can configure the module either by passing options directly within the modules array or by using a top-level viewport key in your nuxt.config.js.
Option 1: Inline module configuration
{
modules: [
[
'nuxt-viewport', {
/* Viewport options */
}
],
]
}Option 2: Top-level configuration
{
modules: [
'nuxt-viewport',
],
viewport: {
/* Viewport options */
},
}The viewport configuration object allows you to define custom breakpoints, device mapping, and cookie settings.
breakpoints (Object): A map where keys are viewport names and values are the size (e.g., { desktop: 1024 }).cookie (Object): Options for the cookie used to persist viewport detection (compatible with cookiejs).defaultBreakpoints (Object): Maps detected devices (bot, desktop, mobile, tablet, tv) to specific breakpoint keys.fallbackBreakpoint (String): The breakpoint key used if the device cannot be detected. Defaults to 'viewport' (Note: the README example uses 'desktop').feature (String): The CSS media feature to use. Either 'minWidth' or 'maxWidth'. Defaults to 'minWidth'.{
viewport: {
breakpoints: {
xs: 320,
sm: 640,
md: 768,
lg: 1024,
xl: 1280,
'2xl': 1536,
},
defaultBreakpoints: {
desktop: 'lg',
mobile: 'xs',
tablet: 'md',
},
fallbackBreakpoint: 'lg'
}
}{
// ...
viewport: {
breakpoints: {
desktop: 1024,
desktopMedium: 1280,
desktopWide: 1600,
mobile: 320,
mobileMedium: 375,
mobileWide: 425,
tablet: 768,
},
cookie: {
expires: 365, // 365 days
name: 'viewport',
path: '/',
sameSite: 'Strict',
secure: true,
},
defaultBreakpoints: {
desktop: 'desktop',
mobile: 'mobile',
tablet: 'tablet',
},
fallbackBreakpoint: 'desktop',
feature: 'minWidth',
},
// ...
}You can also access the viewport instance through the Nuxt app context using $viewport.
<script setup>
import { useNuxtApp } from '#app'
const { $viewport } = useNuxtApp()
watch($viewport.breakpoint, (newBreakpoint, oldBreakpoint) => {
console.log('Breakpoint updated:', oldBreakpoint, '->', newBreakpoint)
})
</script>
<template>
<div v-if="$viewport.isLessThan('tablet')">
Should render only on mobile
</div>
<div v-else>
Current breakpoint: {{ $viewport.breakpoint }}
</div>
</template><script setup>
import { useNuxtApp } from '#app'
const { $viewport } = useNuxtApp()
watch($viewport.breakpoint, (newBreakpoint, oldBreakpoint) => {
console.log('Breakpoint updated:', oldBreakpoint, '->', newBreakpoint)
})
</script>
<template>
<div v-if="$viewport.isLessThan('tablet')">Should render only on mobile</div>
<div v-else>Current breakpoint: {{ $viewport.breakpoint }}</div
</template>The recommended way to access viewport information in your components is via the useViewport() composable. This provides access to the current breakpoint and various helper methods for conditional rendering.
<script setup>
const viewport = useViewport()
// Watch for breakpoint changes
watch(viewport.breakpoint, (newBreakpoint, oldBreakpoint) => {
console.log('Breakpoint updated:', oldBreakpoint, '->', newBreakpoint)
})
</script>
<template>
<div v-if="viewport.isLessThan('tablet')">
Should render only on mobile
</div>
<div v-else>
Current breakpoint: {{ viewport.breakpoint }}
</div>
</template><script setup>
const viewport = useViewport()
watch(viewport.breakpoint, (newBreakpoint, oldBreakpoint) => {
console.log('Breakpoint updated:', oldBreakpoint, '->', newBreakpoint)
})
</script>
<template>
<div v-if="viewport.isLessThan('tablet')">Should render only on mobile</div>
<div v-else>Current breakpoint: {{ viewport.breakpoint }}</div>
</template>The viewport object (accessed via useViewport() or $viewport) provides the following properties and methods:
breakpoint (String): The name of the current breakpoint.queries (Object): An object containing generated media queries.breakpointValue(name: string): number: Returns the numeric value of the specified breakpoint.isGreaterThan(name: string): boolean: Returns true if the current breakpoint is greater than the specified name.isGreaterOrEquals(name: string): boolean: Returns true if the current breakpoint is greater than or equal to the specified name.isLessThan(name: string): boolean: Returns true if the current breakpoint is less than the specified name.isLessOrEquals(name: string): boolean: Returns true if the current breakpoint is less than or equal to the specified name.match(name: string): boolean: Returns true if the current breakpoint matches the specified name.matches(...names: string[]): boolean: Returns true if the current breakpoint matches any of the provided names.You can map specific device categories to your defined breakpoints and specify a fallback behavior.
defaultBreakpoints: Maps semantic names (like mobile or desktop) to your specific breakpoint keys.fallbackBreakpoint: The breakpoint to use if the viewport cannot be determined (default: 'desktop').feature option determines the mechanism used for viewport detection. The default value is 'minWidth'.The nuxt-viewport module is configured using the viewport key in your nuxt.config.ts. The configuration options follow the ViewportOptions type. The module automatically extends your provided options with defaults via extendOptions during setup.
export default defineNuxtConfig({
viewport: {
// Your configuration options here
}
})To prevent layout shifts and ensure consistent viewport detection across requests, nuxt-viewport uses cookies. You can customize the following cookie options:
expires: Number of days until the cookie expires (default: 365).name: The name of the cookie (default: 'viewport').path: The cookie path (default: '/').sameSite: The SameSite attribute (default: 'Strict').secure: Whether the cookie requires a secure connection (default: true).When configuring the nuxt-viewport module, you can provide a ViewportOptions object to customize how breakpoints, cookies, and device detection behave.
Key configuration properties include:
breakpoints: A record mapping breakpoint names to their pixel widths (e.g., { mobile: 480, tablet: 768 }).cookie: Configuration for the viewport cookie, extending standard CookieOptions. You can specify a custom name.defaultBreakpoints: A mapping of device types to breakpoint names for automatic detection. Supported device types are "bot", "desktop", "mobile", "tablet", and "tv".fallbackBreakpoint: The string name of the breakpoint to use if detection fails.feature: Determines the CSS media feature used for calculations. Use 'maxWidth' or 'minWidth'.// Example configuration object
const options: ViewportOptions = {
breakpoints: {
sm: 640,
md: 768,
lg: 1024
},
cookie: {
name: 'my-viewport-cookie'
},
defaultBreakpoints: {
mobile: 'sm',
tablet: 'md',
desktop: 'lg'
},
fallbackBreakpoint: 'lg',
feature: 'maxWidth'
}