Fast, Optimized & SEO-friendly
with Nuxt modules
@mayashavin
Senior Front-end Developer
Core maintainer  @StorefrontUI
Vuejs Israel Organizer
BloggerÂ
Ambassador
The performance audit
Is "being fast" enough for performance ?
Media Optimization
On-the-fly resize images/videos
Auto-deliver optimized format per browser
Reactive transformations on images/videos
Optimize images from non-Cloudinary urls
examples/avatar.png
Use @nuxtjs/cloudinary
/* nuxt.config.js */
export default {
modules: [
'@nuxtjs/cloudinary'
],
cloudinary: {
cloudName: '<your-cloud-name>'
}
}
$cloudinary
Use @nuxtjs/cloudinary
/* nuxt.config.js */
export default {
modules: [
'@nuxtjs/cloudinary'
],
cloudinary: {
cloudName: '<your-cloud-name>',
useComponent: true
}
}
<cld-image />
<cld-video />
Use @nuxtjs/cloudinary
/* pages/avatar.vue */
export default {
computed: {
avatar() {
return this.$cloudinary().url(
`examples/avatar.png`, {
width: 150,
height: 100,
radius: 'max',
crop: 'thumb',
quality: 'auto',
fetchFormat: 'auto'
})
}
}
}
<!-pages/avatar.vue-->
<template>
<div>
<img :src="avatar" alt="cat avatar">
</div>
</template>
Use @nuxtjs/cloudinary
Use @nuxtjs/cloudinary
<cld-image public-id="examples/avatar.png" responsive />
Styling
Optimization
Zero configuration
Minimal CSS with PurgeCSS included
Extendable and customizable CSS
Integration with other Nuxt modules
/* nuxt.config.js */
export default {
buildModules: [
'@nuxtjs/tailwindcss'
],
tailwindcss: {
// options
}
}
Use @nuxtjs/tailwindcss
/* tailwind.config.js*/
module.exports = {
theme: {},
variants: {},
plugins: [],
purge: {
enabled: process.env.NODE_ENV === 'production',
content: [
'components/**/*.vue',
'layouts/**/*.vue',
'pages/**/*.vue',
'plugins/**/*.js',
'nuxt.config.js'
]
}
}
${prefix-for-css-property}-${color-key}-${modifier}
Use @nuxtjs/tailwindcss
Dark mode Support
nuxt/color-mode
@nuxtjs/color-mode
Setup @nuxtjs/color-mode
/* nuxt.config.js */
export default {
buildModules: [
'@nuxtjs/color-mode'
],
//external
colorMode: {
// default value of $colorMode.preference
preference: 'system',
// fallback value if not system preference found
fallback: 'light',
hid: 'nuxt-color-mode-script',
globalName: '__NUXT_COLOR_MODE__',
componentName: 'ColorScheme'
}
}
Use @nuxtjs/color-mode
.${color}-mode
$colorMode
$colorMode = {
preference, //actual selected color-mode
value, //read-only, for detecting system color mode
unknown //boolean - to check if need a placeholder
}
CSS Variables
/* assets/colormode.css */
:root {
--color: #243746;
--color-primary: #158876;
--bg: #f3f5f4;
}
.dark-mode {
--color: #ebf4f1;
--color-primary: #41b38a;
--bg: #091a28;
}
.sepia-mode {
--color: #433422;
--color-secondary: #504231;
--bg: #f1e7d0;
}
body {
background-color: var(--bg);
color: var(--color);
transition: background-color .3s;
}
a {
color: var(--color-primary)
}
+ TailwindCSS
yarn add @nuxt/tailwindcss tailwindcss-dark-mode
/* ~/tailwind.config.js */
module.exports = {
theme: {
darkSelector: '.dark-mode',
},
variants: {
backgroundColor: ['dark', 'dark-hover'],
borderColor: ['dark', 'dark-focus'],
textColor: ['dark', 'dark-hover', 'dark-active']
},
plugins: [require('tailwindcss-dark-mode')()]
}
<button
class="btn border border-black dark:border-white"
@click="changeMode"
>
Button
</button>
/* nuxt.config.js */
export default {
buildModules: [
'@nuxtjs/tailwindcss'
],
}
SEO Optimization
nuxt/robots
nuxt/feed
nuxt/i18n
nuxt/sitemap
@nuxtjs/sitemap
// nuxt.config.js
export default {
modules: [
'@nuxtjs/sitemap'
],
sitemap: {
hostname: 'your-host-name',
exclude: ['/secret', '/admin/**'],
routes: async () => {
const { $content } = require('@nuxt/content')
const { data } = await $content('posts', { deep: true }).fetch()
return data.map((post) => `/articles/${post.slug}`)
}
}
}
@nuxtjs/feed for RSS Feed
// nuxt.config.js
export default {
modules: [
'@nuxtjs/feed'
],
feed: async () => {
const { $content } = require('@nuxt/content')
const posts = await $content('posts', { deep: true, text: true }).fetch()
return [{
path: 'feed.xml',
create(feed) {
feed.options = {
title: `Feed`,
link: 'https://example.com/feed.xml',
description: `Feed`
}
posts.forEach(post => {
feed.addItem({
title: post.title,
id: post.slug,
link: `https://example.com/${post.slug}`,
description: post.description,
content: post.text
})
})
},
cacheTime: 1000 * 60 * 15,
type: 'rss2'
}]
},
}
@nuxtjs/robots
// nuxt.config.js
export default {
modules: [
'@nuxtjs/robots'
],
robots: {
/* module options */
}
}
/* /robots.txt */
User-agent: *
Disallow: '/'
nuxt-i18n
// nuxt.config.js
export default {
modules: [
'nuxt-i18n'
],
i18n: {
locales: ['en', 'fr'],
defaultLocale: 'en',
vueI18n: {
fallbackLocale: 'en',
messages: {
en: require("./locales/en.json"),
fr: require("./locales/fr.json"),
}
}
}
}
Service worker registration for offline
Auto-generate manifest.json
Auto-add SEO-friendly meta data
Push notification with OneSignal
@nuxtjs/pwa
// nuxt.config.js
export default {
modules: [
'@nuxtjs/pwa'
],
pwa: {
icon: {},
meta: {},
manifest: {},
workbox: {}
}
}
Extra
nuxt/auth
Summary
nuxt/cloudinary for media optimization
nuxt/tailwind for CSS styling & theming
nuxt/color-mode for dark/light mode
nuxt/robots, nuxt/feed, nuxt/sitemap for SEO
nuxt/i18n for internalization
nuxt/pwa for PWA support and SEO optimization
THANK YOU
Fast, optimized & SEO friendly apps with Nuxt
By Maya Shavin
Fast, optimized & SEO friendly apps with Nuxt
- 1,084