Power up your Jamstack with Nuxt v2.13+

@mayashavin

Maya Shavin

@mayashavin

Sr. Frontend Developer

Core maintainer @StorefrontUI

Organizer @VueJSIsrael

Blogger

Bookworm

@mayashavin

stack

@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

The current status

before v2.13

Nuxt for Jamstack ?

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

100%

Static?

Theming support?

@mayashavin

So... what's new?

@mayashavin

with V2.13+

Full static

@mayashavin

Smarter build process

deploy

static site

templates

contents

nuxt generate

static HTMLs

payload file for extra client API calls

deploy

static site

@mayashavin

Faster deployments

templates

contents

generate

build

static site

first deploy (or code changes)

contents

next deploy (only contents changed)

nuxt generate

nuxt generate

cached builds

@mayashavin

Dynamic routes generator

/* 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

Optimize performance

🔥 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

Developer & User Experience

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

Headless CMS 

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

@nuxt/content

🔥 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 &amp; adipisicing
blah blah blah blah blah blah

@mayashavin

yarn add @nuxt/content

Setup @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

Use @nuxt/content

/* 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

@nuxt/content Hooks

content:file:beforeInsert
content:update

Add data before storing document

When CMS content is updated

@mayashavin

Documetation with theme

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

Documentation with theme

@mayashavin

@mayashavin

Dark mode support

with @nuxtjs/color-mode

& @nuxtjs/tailwindcss

@mayashavin

@nuxtjs/color-mode

@mayashavin

Setup @nuxtjs/color-mode

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

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'
  ],
}

@mayashavin

@mayashavin

And more features

smarter pre-fetching

built-in component detection

run-time config

telemetry

@mayashavin

Resources

@mayashavin

THANK YOU

@mayashavin