@mayashavin
Maya Shavin
Sr. Frontend Developer
Core maintainer @StorefrontUI
Organizer @VueJSIsrael
Blogger
Bookworm
@mayashavin
@mayashavin
JavaScript
API
Markup
frontend
reusable APIs
serverless functions
build-time
backend
web servers
databases
run-time
template generating
file-driven
data-driven
page generating
SSR
Static site generator (SSG)
Single page app (SPA)
Single code base
Build
@mayashavin
@mayashavin
before v2.13
External run-time Client-side API calls for data
@mayashavin
NO built-in Markdown support
NO auto dynamic routes generation for data
LONG building time
Theming support?
@mayashavin
@mayashavin
@mayashavin
deploy
static site
templates
contents
nuxt generate
static HTMLs
payload file for extra client API calls
deploy
static site
@mayashavin
templates
contents
generate
build
static site
first deploy (or code changes)
contents
next deploy (only contents changed)
nuxt generate
nuxt generate
cached builds
@mayashavin
/* nuxt.config.js */
generate: {
async routes() {
const { $content } = require('@nuxt/content')
const files = await $content()
.only(['blog/posts'])
.fetch()
return files.map(file => file.path))
}
}
🔥 Auto-detect & generate links by crawler
@mayashavin
🔥 Faster re-deployment
🔥 Smaller generated HTML files size
🔥 NO external client-side data API calls
static HTMLs
payload file for extra client API calls
preload
🔥 Faster building time
🔥 Faster app
🔥 Crawler integrated
(detect and generate relative links)
@mayashavin
target: 'static'
Enable fallback on redirects & errors (client-side rendering)
Better DX + UX
nuxt serve
Production HTTP server for static app
SPA fallback support
Better local testing before deployment
@mayashavin
nuxt generate
nuxt generate (content changes)
~35s
~12s
@mayashavin
with @nuxt/content
@mayashavin
🔥 Search support (using LokiJS)
🔥 MongoDB-like QueryBuilder API
🔥 Support for Vue components (Markdown)
🔥 Built-in Code highlighting (PrismJS)
🔥 Auto-generating table of content
🔥 Hot CMS reload & content hooks
🔥 Various files support
/*sample-artilce.md*/
## Hello Heading 2
This is paragraph 2.
<cld-image
public-id="nuxt_demo/DSC00856"
class="my-3"
crop="fill"
responsive
quality="auto"
fetch-format="auto"
/>
// get all files with only selected fields
const pages = await $content('blog/posts')
.only([
'title',
'description'])
.fetch()
const posts = await this.$content('posts')
.only(['title', 'date', 'author'])
.sortBy('date', 'asc')
.limit(5)
.skip(10)
.where({
tags: 'javascript',
isArchived: false,
date: { $gt: new Date(2020) },
})
.search('nuxt')
.fetch()
```js
function foo() {
var a = 42,
b = 'Prism';
return a + bar(b);
}
```
# Lorem ipsum
blah blah
## dolor—sit—amet
blah blah blah blah
### consectetur & adipisicing
blah blah blah blah blah blah
@mayashavin
yarn add @nuxt/content
/* nuxt.config.js */
modules: [
'@nuxt/content'
],
content: {
dir: 'content',
fullTextSearchFields: ['title', 'description'],
markdown: {
remarkExternalLinks: {
target: '_blank',
rel: 'noopener noreferrer'
},
remarkPlugins: ['remark-emoji'],
prism: {
theme: 'prism-themes/themes/prism-a11y-dark.css'
}
}
},
@mayashavin
/* example-page.vue */
<script>
export default {
async asyncData({ $content }) {
//get content/example file
const page = await $content('example')
.fetch();
return { page }
}
}
</script>
<!-- example-page.vue -->
<template>
<div>
<nuxt-content :document="page" />
</div>
</template>
@mayashavin
content:file:beforeInsert
content:update
Add data before storing document
When CMS content is updated
@mayashavin
yarn create nuxt-content-docs <your-docs>
{
"title": "Nuxt Content",
"url": "https://content.nuxtjs.org",
"logo": {
"light": "/logo-light.svg",
"dark": "/logo-dark.svg"
},
"github": "nuxt/content",
"twitter": "@nuxt_js"
}
module.exports = {
theme: {
extend: {
colors: {
primary: {
100: '#FCEDEE',
200: '#F8D3D5',
300: '#F3B9BB',
400: '#EB8488',
500: '#E24F55',
600: '#CB474D',
700: '#882F33',
800: '#662426',
900: '#44181A'
}
}
}
}
}
content/settings.json
tailwind.config.js
@mayashavin
@mayashavin
with @nuxtjs/color-mode
& @nuxtjs/tailwindcss
@mayashavin
@mayashavin
yarn add --dev @nuxtjs/color-mode
#OR
npm install --save-dev @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'
}
}
@mayashavin
.${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)
}
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'
],
}
@mayashavin
@mayashavin
smarter pre-fetching
built-in component detection
run-time config
telemetry
@mayashavin
@mayashavin
@mayashavin