docs: function(options) {
      if (!options) throw new Error('You must pass options to PageCompiler')
  
      const baseUrl = options.baseUrl; validateBaseUrl(baseUrl)
      const baseHref = options.baseHref; validateBasePath(baseHref)
      const basePath = options.basePath; validateBasePath(basePath)
      const database = options.database; validateDatabase(database)
      const userGlobals = options.globals || {}; validateGlobals(userGlobals)
  
      // parse all page entries before rendering any. This way, if a developer has two
      // config errors and one render error, fixing the first config error will make
      // the second config error throw: when a render error is thrown, the developer
      // knows there are no config errors.
      validatePages(options.pages)
      const pageEntries = options.pages.map(e => new PageEntry(baseHref, database, e))
  
      const routes = new PageRouter(baseUrl, pageEntries)
  
      const globals = Object.assign({}, userGlobals, {
        routes: routes
      })
  
      const renderer = new Renderer(basePath, routes, globals)
  
      const endpoints = []
      for (const pageEntry of pageEntries) {
        for (const { href, model } of pageEntry.hrefs) {
          endpoints.push(renderer.renderEntry(pageEntry, href, model))
        }
      }
  
      return new StaticWebsite(endpoints)
    }