npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ember-build-prerender

v0.3.2

Published

Prerender Ember pages with Puppeeter.

Downloads

17

Readme

ember-build-prerender

An addon to prerender your Ember app with Puppeteer into static HTML files.

Compatibility

  • Ember.js v3.24 or above
  • Ember CLI v3.24 or above
  • Node.js v12 or above

Installation

ember install ember-build-prerender

Usage

ember prerender

# To see all available options
ember help prerender

ember prerender can be considered mostly a drop-in replacement for ember build. There are some additional options to pass:

# Prerender a list of urls
ember prerender --urls="/" --urls="/page-1" --urls="/page2/sub"

# Prerender with a url fetcher - see below for details
ember prerender --url-fetcher="./lib/my-url-fetcher.js"

# Change viewport for prerendered pages
ember prerender --viewport-width=1920 --viewport-height=1080

URL fetchers

The --url-fetcher argument should be a path relative to the project root to a node module. This node module should export an async function which returns an array of URLs, which is merged with the given array of --urls.

The function has the following signature:

// lib/my-url-fetcher.js
module.exports = async function myUrlFetcher(page, visit) {
  // `visit` is a helper function that accepts a URL/path and will open this page in Puppeteer
  // It returns a promise that resolves when the page finished loading
  await visit('/');

  // `page` is the Puppeteer page instance. You can use all Puppeteer APIs on it
  let urls = await page.$$eval('a', (aTags) =>
    aTags.map((aTag) => aTag.getAttribute('href'))
  );

  // Return an array of URLs
  return urls;
};

View docs for Puppeteer pages for details.

The prerender service

There is also a service to use, if you need/want to have different behavior in prerender mode:

// app/components/my-component.js
export default class MyComponent extends Component {
  @service prerender;

  get isDisabled() {
    // Returns `true` when prerendering, else `false`
    return this.prerender.isPrerender;
  }
}

The prerender service also provides a simple shoebox (similar to ember-cli-fastboot) to store & exchange data between the prerender and the rehydration phases:

export default class MyComponent extends Component {
  @service prerender;

  async loadData() {
    if (this.prerender.isPrerender) {
      let data = await loadDataFromApi();
      this.prerender.shoebox.set('api-data', data);
      return data;
    } else {
      return this.prerender.shoebox.get('api-data');
    }
  }
}

Any data you set via shoebox.set() will be JSON-stringified, and can be retreived with the same key via shoebox.get(). Note that you can only set data in prerender mode. The shoebox will be stored in a meta tag in the document.

Note that in dev mode the shoebox will be empty. So any non-prerender code should never rely on any shoebox content to exist, but instead treat it as optional.

How it works

ember-prerender basically works in four steps:

  1. Build the app into a directory (basically ember build --prod)
  2. Start a local server with http-server serving the build
  3. Start a Puppeteer instance to view & prerender the given URLs
  4. Merge the prerendered pages with the original build output, renaming the original index.html to _empty.html

The app will rehydrate from the static HTML files, providing a smooth transition from the static page to a fully booted Ember app.

Difference to ember-cli-fastboot / prember

In contrast to ember-cli-fastboot, this addon will prerender the app using a "regular" browser (Chrome via Puppeteer). This has the benefit of running all code normally - modifiers etc. will all run just like they do normally.

The restriction is that this only works for prerendering. You can not run this in production like ember-cli-fastboot. As such, it is only a possible replacement for prember, which uses fastboot to prerender your app.

It uses the same serialization/rehydration code under the hood (which lives directly in Glimmer nowadays) as fastboot does.

Integration into build/deployment process

You can use an ember-cli-deploy plugin for easy integration into your pipeline:

ember-cli-deploy-prerender can be used as a mostly drop-in replacement for ember-cli-deploy-build.

Trying prerendering in development

This addon does not have a true development integration as of now. To test the full prerendering flow, you can use the following:

# Prerender app with your desired settings - make sure to set empty file to 404.html
ember prerender --empty-file="404.html"

# Start local server
npx http-server dist -c-1

This will start a local server in the prerendered dist/ directory, which you can view under http://localhost:8080.

Contributing

See the Contributing guide for details.

License

This project is licensed under the MIT License.