How to pass server data/context to a webpack generated Vue SSR application using vue-ssr-renderer?

Viewed 729

Following various tutorials and guides, I was able to get basic SSR Vue working with Webpack, the problem is I can't seem to be able to pass server data/context to the app. I'm using Vue SSR Renderer's bundle renderer. My express /router.js looks like this:

const express = require("express");
const fs = require('fs');
const { resolve } = require('path');
const { createBundleRenderer } = require('vue-server-renderer');

const router = express.Router();

const renderer = createRenderer();

router.get('*', (req, res) => {
  const context = { url: req.url };
  renderer.renderToString(context, (err, html) => {
    if (err) {
      console.error(err);
      return res.status(500).end(err.message);
    }
    return res.end(html)
  });
});

function createRenderer() {
  const bundlePath = resolve(__dirname, './dist/server.bundle.js');
  const template = fs.readFileSync('./index.html', 'utf-8');
  return createBundleRenderer(bundlePath, { template }); // https://ssr.vuejs.org/api/#createbundlerenderer
}

module.exports = router;

The problem happens when it consumes my server bundle, produced by /src/entry.server.js:

import { createApp } from './main.js';

export default context => new Promise((resolve, reject) => {
  const { app } = createApp(context);
  resolve(app);
});

which consumes /src/main.js

import Vue from 'vue';
import App from './App.vue';

export function createApp(context = {}) {
  const app = new Vue({
    render: h => h(App)
  });

  return { app };
}

Here, the problem is that when I try to use the included server context as a data property, it evaluates to undefined and I have no idea why. Like so:

import Vue from 'vue';
import App from './App.vue';

export function createApp(context = {}) {
  const app = new Vue({
    render: h => h(App),
    data() {
      return { url: context:url }
    }
  });

  return { app };

I tried making data an arrow function in case it was a scoping issue, but that didn't solve it. I tried hardcoding url to a string, and that works and is shown on the client, which tells me the problem is the context variable not being sent correctly.And the API docs of vueServerRenderer.bundleRenderer() do a poor job explaining how to pass data to the bundle.

I know this is a problem that could be solved using Nuxt or Vuex, but I'm really trying to keep things minimal and only rely on them until I absolutely need them.

Any ideas how I could solve this?

You can find and clone the entire project here, and find the entire webpack server and client configurations there as well:

https://github.com/sgarcia-dev/minimal-vue-ssr-webpack

0 Answers
Related