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

Power up your Jamstack with the new Nuxt

By Maya Shavin

Power up your Jamstack with the new Nuxt

Let’s explore how to give your site the full power of JAMstack, with the latest Nuxt features. Performance can be achieved easily with the simplest stack!

  • 1,526