In modern web development, performance is SEO.
Search engines now care not only about page content but also load speed, image optimization, and meta data.
Enter two Nuxt modules: @nuxt/image and @nuxt/seo.
Here’s how to use them together to supercharge your performance scores.
1) Nuxt Image — Autopilot for image optimization
Images can easily make up more than 60% of a page’s weight. Nuxt Image lightens that load. It’s a smarter<img>: under the hood it compresses, resizes, converts formats, and caches—automatically.Install
1️⃣ Add the package:
npm install @nuxt/image
2️⃣ Enable the module in nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@nuxt/image']
})
Basic usage
<template>
<NuxtImg src="/images/hero.jpg" width="800" height="400" alt="Hero image" />
</template>
Nuxt will optimize the image, serve modern formats (webp, avif) when possible, and apply lazy-loading.
Features
- Lazy Loading: Only loads when visible.
- Format Conversion: Serves WebP/AVIF where supported.
- Responsive Breakpoints: Generates sizes for different screens.
- Cache & CDN: Integrates with Cloudinary, IPX, ImageKit, etc.
Responsive example
<NuxtImg
src="/images/banner.jpg"
sizes="sm:400px md:800px lg:1200px"
format="webp"
alt="Responsive Banner"
/>
Each viewport gets the most appropriate size—Lighthouse loves this.
Local optimization with IPX
By default, Nuxt Image uses IPX for local/CDN processing.
image: {
domains: ['cdn.site.com'],
provider: 'ipx',
quality: 80,
screens: { sm: 320, md: 768, lg: 1200 }
}
💡 Tip: Put images in assets/ (not public/) to run them through the IPX pipeline for compression and caching.
2) Nuxt SEO — Automate meta tags
In Nuxt 3, SEO is a system, not a snippet. The @nuxt/seo module manages meta tags, Open Graph, Twitter Cards, and structured data.
Install
1️⃣ Add the package:
npm install @nuxt/seo
2️⃣ Enable it in nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@nuxt/seo']
})
Basic usage
<script setup>
useSeoMeta({
title: 'Nuxt 3 SEO Example',
description: 'Automate SEO meta tag management',
ogImage: '/images/preview.jpg',
twitterCard: 'summary_large_image'
})
</script>
useSeoMeta lets you define per-page dynamic meta tags.
Dynamic titles
useHead({
titleTemplate: (title) => `${title} | MySite`
})
A clean way to append your brand everywhere.
Open Graph & Schema
The SEO module manages Open Graph and Twitter meta.
It also supports structured data (schema.org JSON-LD) to enrich search snippets.
useSchemaOrg([
defineWebSite({ name: 'MySite', url: 'https://mysite.com' }),
defineWebPage({ name: 'Blog Post', description: 'Technical content on Vue, Nuxt, and React.' })
])
Result: Google no longer guesses—you describe the page.
Strategy: use them together
Performance + SEO = win-win.
The example below shows how to optimize both:
<template>
<article>
<NuxtImg src="/images/article-cover.jpg" alt="Blog Cover" width="1200" height="630" />
<h1>{{ post.title }}</h1>
<p>{{ post.description }}</p>
</article>
</template>
<script setup>
const { data: post } = await useAsyncData('post', () => $fetch('/api/post'))
useSeoMeta({
title: post.value.title,
description: post.value.description,
ogImage: '/images/article-cover.jpg',
twitterCard: 'summary_large_image'
})
</script>
What you get:
- Optimized image delivery
- Lazy loading
- Dynamic SEO meta
- Full SSR content for crawlers 🔍
Things to watch out for
- Always set
widthandheightonNuxtImgto prevent CLS. - Avoid duplicate meta tags—multiple
title/descriptionentries can confuse crawlers. - Call
useSeoMetainsidesetup()so reactive values stay in sync.
Extra tips for Lighthouse
- Prefer AVIF where possible.
- Tune lazy-load thresholds with
IntersectionObserver. - Add
meta[name='theme-color']for better mobile UX. - Generate a sitemap (e.g.,
@nuxtjs/sitemap) for indexing.
npm install @nuxtjs/sitemap
export default defineNuxtConfig({
sitemap: {
siteUrl: 'https://mysite.com',
autoLastmod: true
}
})
Conclusion
Used together, Nuxt Image and SEO modules boost visual performance and search visibility.
In short:
NuxtImg→ faster, responsive, compressed imagesuseSeoMeta→ accurate meta, richer resultsuseSchemaOrg→ tell Google exactly who you are