Skip to content

A Nuxt module to serialiser / deserialise class instances on SSR mode

License

Notifications You must be signed in to change notification settings

Kapcash/nuxt-ssr-class-serialiser

Repository files navigation

nuxt-ssr-class-serialiser

npm version licence badge

Features

This module help you to deal with - Typescript - class instances transfer from Server side to Client side.

The problem it solves

Whenever you use class instances for your component's data on server side, you'll be likely facing this warning ⚠️:

Warning: can't stringify non-POJO

This is because Nuxt serialises the server side data to JSON, then stringify it, in order to transfer it in an HTTP request to the client side.

But JSON.stringify() doesn't work with class instances! 💥

That's what this module is fixing.

Requirements

I wish I could provide this solution for vanilla components instead of class based one. Sadly, I don't know how to provide the equivalent of Typescript decorators for vanilla code...

Setup

  1. Add nuxt-ssr-class-serialiser dependency to your project
yarn add nuxt-ssr-class-serialiser # or npm install nuxt-ssr-class-serialiser
  1. Add nuxt-ssr-class-serialiser to the modules section of nuxt.config.js
{
  modules: [
    'nuxt-ssr-class-serialiser',
  ],
}

Usage

The module provides a custom decorator SerialiseClass to decorate the data you need to serialise.

import { Vue, Component } from 'nuxt-property-decorator'
import { SerialiseClass } from '../../src/serialiser-class-decorator'
import { Todo, fetchTodo } from '../models/todo'

export class Todo implements ITodo {
  id!: number;
  description!: string;
  dueDate!: string;

  get isExpired (): boolean {
     const dueDate = new Date(this.dueDate)
     const today = new Date()
     return dueDate < today
  }
}

@Component
export default class Page extends Vue {
  // Identify the data as a serialisable class instance
  // You have to pass in the class constructor as parameter
  @SerialiseClass(Todo)
  todo!: Todo

  async asyncData() {
    // Return a todo *instance* (new Todo()), not a plain object
    const todo: Todo = await fetchTodo()

    return {
      todo,
    }
  }
}

In class components, asyncData returned properties are not properly types. If you try to run this.todo, it won't exist for Typescript.

A solution for this is to declare it as a class property as above.
That's where we can use the decorator.

Decorator Parameters Description
SerialiseClass (classConstructor) Mark the decorated property as serialisable. Provide the constructor to use as parameter.

Development

  1. Clone this repository
  2. Install dependencies using yarn add or npm install
  3. Start the example nuxt app using yarn dev or npm run dev

License

MIT License

About

A Nuxt module to serialiser / deserialise class instances on SSR mode

Resources

License

Stars

Watchers

Forks

Packages

No packages published