Nuxt - sgml/signature GitHub Wiki

Modules

WAI-ARIA: https://vue.chakra-ui.com/accessibility

API

  • "nuxt" "context" "route" "name" site:v2.nuxt.com middleware

Offline Prerenderer

File Structure

project-root/
├── dist/
│   └── MyComponent.js            # Pre-bundled script (optional with Vite, Grunt, etc.)
├── src/
│   └── MyComponent.vue          # Your Vue 2 SFC with template/script/style
├── output.html                  # SSR-rendered output HTML
├── vue2-offline-renderer.js     # Main renderer script using vue-template-compiler
├── vite.config.js               # Optional if using Vite to bundle scripts
├── Gruntfile.js                 # Optional for pre-bundling with Grunt + Browserify
├── gulpfile.js                  # Optional for legacy Gulp support
├── package.json
└── node_modules/

Vue 2

/**
 * Setup:
 * npm install vue vue-server-renderer vue-template-compiler @vue/component-compiler-utils postcss postcss-selector-parser
 *
 * Run:
 * node vue-offline-renderer.js
 */

// 👉 Vue 2: https://www.npmjs.com/package/vue
// 👉 Vue 3 equivalent: https://github.com/vuejs/core (via `vue` export)
const Vue = require('vue');

// 👉 Vue 2: https://www.npmjs.com/package/vue-server-renderer
// 👉 Vue 3 equivalent: https://github.com/vuejs/core/tree/main/packages/server-renderer
const renderer = require('vue-server-renderer').createRenderer();

// 👉 Node.js core modules (no Vue 3 equivalent needed)
const fs = require('fs');
const path = require('path');

// 👉 Vue 2: https://www.npmjs.com/package/vue-template-compiler
// 👉 Vue 3 equivalent: https://github.com/vuejs/core/tree/main/packages/compiler-sfc
const compiler = require('vue-template-compiler');

// 👉 Vue 2 utility wrapper: https://www.npmjs.com/package/@vue/component-compiler-utils
// 👉 Vue 3 equivalent: superseded by `@vue/compiler-sfc` → https://github.com/vuejs/core/tree/main/packages/compiler-sfc
const compilerUtils = require('@vue/component-compiler-utils');

// 👉 PostCSS: universal processor used in both Vue 2 and 3
const postcss = require('postcss');

// 👉 Used in scoped style transformation; not Vue-specific
const selectorParser = require('postcss-selector-parser');

Vue 3

/**
 * Setup:
 * npm install vue @vue/compiler-sfc @vue/server-renderer postcss postcss-selector-parser
 *
 * Run:
 * node vue3-offline-renderer.js
 */

// 👉 Vue 3 core: https://github.com/vuejs/core/tree/main/packages/vue
const { createSSRApp } = require('vue');

// 👉 Vue 3 SSR renderer: https://github.com/vuejs/core/tree/main/packages/server-renderer
const { renderToString } = require('@vue/server-renderer');

// 👉 Vue 3 SFC compiler: https://github.com/vuejs/core/tree/main/packages/compiler-sfc
const { parse, compileTemplate } = require('@vue/compiler-sfc');

const fs = require('fs');
const path = require('path');

// 👉 PostCSS: used in Vue 2 & 3 for style transforms
const postcss = require('postcss');

// 👉 Scoped style emulation: not Vue-specific
const selectorParser = require('postcss-selector-parser');

// Load and parse the .vue file
const filePath = path.resolve(__dirname, 'MyComponent.vue');
const source = fs.readFileSync(filePath, 'utf-8');
const { descriptor } = parse(source);

const scopeId = `data-v-${Math.random().toString(36).slice(2, 5)}`;

// Compile template into a render function
const { code: renderCode } = compileTemplate({
  source: descriptor.template.content,
  filename: 'MyComponent.vue',
  id: scopeId,
  scoped: true,
  compilerOptions: {
    mode: 'function',
  },
});

// Evaluate the <script> content
const exports = {};
new Function('module', 'exports', descriptor.script?.content || '')({ exports }, exports);

// Process scoped <style> block
let scopedCSS = '';
const style = descriptor.styles.find(s => s.scoped);
if (style) {
  postcss([
    root => {
      root.walkRules(rule => {
        rule.selectors = rule.selectors.map(sel =>
          selectorParser(selector => {
            selector.each(node => {
              node.append(selectorParser.attribute({ attribute: scopeId }));
            });
          }).processSync(sel)
        );
      });
    }
  ])
  .process(style.content, { from: undefined })
  .then(result => {
    scopedCSS = `<style>${result.css}</style>`;
    render();
  });
} else {
  render();
}

// Render component to static HTML
function render() {
  const Component = {
    ...exports,
    render: new Function('Vue', renderCode)(require('vue')),
    __scopeId: scopeId,
  };

  const app = createSSRApp(Component);
  renderToString(app).then(html => {
    const finalHTML = `
      <!DOCTYPE html>
      <html>
        <head>${scopedCSS}</head>
        <body>${html}</body>
      </html>
    `;
    fs.writeFileSync(path.resolve(__dirname, 'output.html'), finalHTML, 'utf-8');
    console.log('✅ HTML written to output.html');
  }).catch(err => {
    console.error('❌ Rendering error:', err);
  });
}

File Structure

  assets:                    # Asset files such as styles, images
    - ...
  components:                # Vue components
    - ...
  composables:               # Composition API functions
    - ...
  content:                   # Content files for @nuxt/content
    - ...
  layouts:                   # Layout components
    - ...
  middleware:                # Middleware functions
    - ...
  pages:                     # Page components for routing
    - ...
  plugins:                   # Plugins to extend Vue
    - ...
  public:                    # Static assets
    - ...
  server:                    # Server-side code (e.g., API routes)
    - ...
  stores:                    # Pinia or Vuex stores
    - ...

ENV

NUXT_TARGET:

{
  "scripts": {
    "generate": "cross-env NUXT_TARGET=static nuxt generate"
  },
  "devDependencies": {
    "cross-env": "^7.0.3"
  }
}

Naming Conventions, Globals, and File Structure

Migrating from Nuxt 2 to Nuxt 3

Pages Directory

  1. New Structure: Nuxt 3 introduces a new directory structure. The pages directory is now used for routing and layout management. In Nuxt 2, you had separate pages and layouts directories.
  2. Dynamic Routes: The format for defining dynamic routes has changed. In Nuxt 2, you used _id for dynamic routes, while in Nuxt 3, you use [id].
  3. Nested Routes: Nuxt 3 uses <NuxtPage> component for nested routes, replacing <Nuxt> and <NuxtChild> from Nuxt 2.
  4. Layouts: Layouts in Nuxt 3 use slots instead of the <Nuxt> component. This allows for more advanced use cases with named and scoped slots.

nuxt.config.js

  1. New Configuration Format: Nuxt 3 uses a new configuration format based on the defineNuxtConfig function, which provides better TypeScript support and an improved developer experience.
  2. TypeScript Support: Nuxt 3 fully embraces TypeScript, making it easier to write type-safe code.
  3. Global Imports: Nuxt 3 automatically identifies and imports core functions like ref and reactive, eliminating the need for manual imports in each component.
  4. Middleware: Nuxt 3 has a revamped middleware system, providing more flexibility and control over your application's behavior.

HTML Specific JavaScript

  • Update HTML templates to use Vue 3 syntax.
  • Replace deprecated Vue 2 directives with Vue 3 equivalents.
  • Ensure all HTML elements are properly bound and updated.

CSS Specific JavaScript

  • Update CSS classes and styles to match the new Nuxt 3 structure.
  • Ensure CSS is properly linked and applied to components.
  • Adjust any CSS-in-JS libraries to work with Vue 3.

VueX to Pinia Specific JavaScript

  • Replace Vuex store setup with Pinia store setup.
  • Migrate Vuex actions, mutations, and state to Pinia equivalents.
  • Update any components that interact with the store to use Pinia.

Routing Specific JavaScript

  • Update routing configuration to use the new Nuxt 3 pages directory.
  • Ensure all routes are properly defined and linked to components.
  • Adjust any programmatic routing code to use the new Nuxt 3 router API.

Static Site Generation via Markdown

Cookbook

CVEs

Storybook

Release Notes / Changelogs / Roadmaps

Async Utilities

  async timeout(context, payload) {
    console.warn('waiting', payload)
    await new Promise((resolve) => setTimeout(resolve, payload))
  }

  async foo(context) {
    await context.dispatch('timeout', 1000)
  }

i18N Utilities

// each param replaces the literal; $route is used instead of this.$route
// for each iteration of foo, use foo.id to get the unique URL
localePath({
  name: 'slug-foos-foo-fooid',
  params: { slug: $route.params.slug, fooid: foo.id }
})

Nginx

Config

https://vuejs.org/v2/guide/deployment.html

https://vue-loader.vuejs.org/guide/pre-processors.html

https://nuxtjs.org/faq/nginx-proxy/

https://www.digitalocean.com/community/tutorials/implementing-authentication-in-nuxtjs-app

https://vuejs-templates.github.io/webpack/structure.html

https://github.com/vuejs/vuejs.org/blob/master/src/v2/guide/components-edge-cases.md#x-templates

https://vuejsdevelopers.com/2017/03/24/vue-js-component-templates/

https://github.com/vuejs/vue/blob/master/examples/tree/index.html

https://stackoverflow.blog/2020/03/25/tracking-down-performance-pitfalls-in-vue-js/?cb=1

https://markus.oberlehner.net/blog/accessible-custom-vue-form-select-component-simple-but-advanced/

https://www.optasy.com/blog/are-there-any-strong-reasons-not-use-nuxtjs-7-issues-might-discourage-you-choosing-it

https://dev.to/vuevixens/dockerise-your-nuxt-ssr-app-like-a-boss-a-true-vue-vixens-story-4mm6

https://jonathanmh.com/deploying-a-nuxt-js-app-with-docker/

https://nuxtjs.org/api/nuxt/

Routing

https://nuxtjs.org/api/components-nuxt-child/

https://zaengle.com/blog/named-routes-in-nuxt

https://router.vuejs.org/guide/essentials/navigation.html

https://farnabaz.ir/@farnabaz/reveal-hidden-capabilities-of-nuxt-router/

https://css-tricks.com/creating-dynamic-routes-in-a-nuxt-application/

https://blog.pusher.com/demystifying-page-transitions-nuxt/

https://nuxt-community.github.io/nuxt-i18n/routing.html

https://www.vuesnippets.com/

Middleware

Lifecycle

Components

Guides

Sample Code

Plugins

buefy / Bulma

v-model

Parser

Vue 2

Vue 3

pub/sub

Internals

Reactivity

References

⚠️ **GitHub.com Fallback** ⚠️