Bootstrapping Request Headers to the App

Hello,

I am experimenting with DoneJS based on the all too common SEO issues encountered with Angular and most AJAX based sites. SEO is very important to my company, and I like what DoneJS and its dependencies do to help with SEO problems. With that said, our app site behind Varnish and we utilize that very heavily to set up custom headers on the request and pass them along to the backend app. How can I get access to the request in the DoneJS app? Any assistance with this would be greatly appreciated to determine whether I move forward with building a Proof of Concept with DoneJS.

Thanks!

Brett,
I actually just went to a meetup on varnish. Seems like a pretty useful tool.

As far as getting the request object, I know there’s a merged pull request for the next release to allow someone full control over the render lifecycle. It allows you to define a module that gets built something like:

var route = require("can/route/");
var ViewModel = require("my-app/app")
var render = require("my-app/index.stache!");

exports.createState = function(request, response){
	var params = route.deparam(request.url);
	return new ViewModel(params)
}
exports.render = function(doc, state){
   doc.documentElement.appendChild( render(state) )
};

Unfortunately, the person who knows the code best is out for the week.

In the mean time, I will try to figure out a solution for you.

Hi Justin,

Thank you for replying so quickly. I just wanted to reach out to see if you were able to work out anything? I am a little confused how I would work that module structure into the app.js file. An example of mine is below:

import AppMap from "can-ssr/app-map";
import route from "can/route/";
import 'can/map/define/';
import 'can/route/pushstate/';

const AppViewModel = AppMap.extend({
  define: {
    message: {
      value: 'test',
      serialize: false
    },
    title: {
      value: 'test again',
      serialize: false
    }
  }
});

export default AppViewModel;

Brett, I haven’t yet unfortunately. I’m focusing on another problem today and tomorrow.

This will probably have to wait until Matthew gets back Monday.

a little confused how I would work that module structure into the app.js file.

The code I shared would be another module that would import your app.js.

Basically, can-ssr needs a module that exports two things:

  • the data used to render a template
  • a render method that takes the data

the done-autorender plugin reads a template and creates one of these modules. However, you can create one of these modules yourself. I’ve just not done it.

Hey @Brett_Cohen, I’m looking into this issue today and will get back with you. I’ve made some changes to can-ssr in a prerelease that will make it more flexible so that you can do stuff like this, so I’ll take this issue into consideration and make sure what you need to do is supported. Expect to hear back from me soon.

Thank you @matthewp!

Hey @Brett_Cohen, we have a new release which adds the raw request object to the AppViewModel, so you can set headers on that or do whatever it is that you need. To get this to work you need:

  • can-ssr: 0.11.0-pre.1
  • done-autorender: 0.6.0-pre.0

Once you’ve updated those there will be a new request property on your AppViewModel.

You can use it like:

const AppViewModel = AppMap.extend({
  define: {
    url: {
      get: function() {
        var request = this.attr("request");
        return request ? request.url : undefined;
      }
    }
  }
});

This is just one example where we are setting a url based on teh request. Note that the request object only exists on the server, so guard against that. Anything on the request object can be used, see the Express docs on what that includes.

1 Like