Dynamic Pages
upmk has the ability to run A/B tests by serving up a specific route with a
variable number of alternate dynamic pages. To accomplish this you'll need the
dyna-pages
modules in verdaccio.
Basics
dyna-pages reads a config file that declares a route and possible responses
to the route. When the user selects that path / route, dyna-pages randomly
selects a response from the config and either 302 redirects to it, or sends a
local file to fullfill the request. Either type of response has a cache control
header. this allows for A/B (split) testing
Usage
cd dynamic
npm i @upmarkers/dyna-pages --save
Config
add app/config/abs.conf to your upmk project
redirect /deal -> /deals/enterprise {{2}}
redirect /deal -> /deals/alternate {{2}}
serve /deal -> /deals/index.html
each entry can have a count (defaults to 1) which is a relative number. in the above there is a 2 in 5 chance that you will get enterprise, and 2 in 5 chance for alternate, and a 1 in 5 chance for the control / index page
for any route (i.e. /deal above), dyna-um will now handle this route. the
static upmk nginx config will still take precedence, so you need to be sure
there are no static pages being served up from this route. (see serve
directive below for more details)
Config Directives
redirect means that dyna-pages will serve up a 302 to the destination
serve will move the destination file out of the static directory and into
dyna-um. should it will send the file (should it be picked randomly)
Installation into dyna-um
create a dynamic/src/dyna/abs.js file:
const dynaPages = require('@upmarkers/dyna-pages')
const absConfig = require('../../abs/config.json')
const { join } = require('path');
const absPath = join(__dirname, '../../abs')
module.exports = dynaPages({root: absPath, config: absConfig})
then add it to your dyna-um middlewares file (dynamic/src/middlewares.js):
const abs = require('./dyna/abs')
function middlewares(app) {
app
.use(json())
.use(cookieParser()) // must be before csrf
.use(abs)
.use(serve(publicPath, {extensions: ['html']}))
.use(csrf({ cookie: true }))
return app
}