Skip to content
Add dynamic content loading to static sites with only 1 KiB of JS
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
bin [utils] Replace ssri with simple checksum generator Apr 1, 2019
docs
example
src [util,src,docs] Bump version. Rewrite to ES5. Add badges Mar 30, 2019
.editorconfig [*] Initial commit Mar 29, 2019
.eslintignore
.eslintrc
.gitignore [*] Initial commit Mar 29, 2019
.npmignore [util] Update npmignore Mar 30, 2019
license
package-lock.json [utils] Replace ssri with simple checksum generator Apr 1, 2019
package.json [docs,util] Bump version. Update cover image and badges layout Apr 3, 2019
readme.md [docs] Fix npm package link Apr 3, 2019
todo.md [docs,src] Remove unpredictable functions. Add todo.md. Update instru… Mar 29, 2019

readme.md

Pill logo

badge: npm version badge: size 1.1 KiB badge: deps 0

Pill adds dynamic content loading to static sites and makes content loading smooth for users. It's pretty small only 1 KiB minified and gzipped. It fits perfectly for static sites with WebComponents.

Pill development started with the tweet by Andrey Sitnik @ai.

How pill works. It:

  1. Intercepts navigation attempts: links clicks and history navigation.
  2. Loads requested url using fetch.
  3. Grabs content from received HTML.
  4. Replaces current page content.

Initialize in one line:

pill('#content') // Yep, that's it.

Table of Contents

Install

  • Include script from unpkg.com:

    <script src="https://unpkg.com/pill@1/dist/pill.min.js"></script>

    ⚠️ Remember about security! Add subresource integrity (SRI) checksum from checksum.txt.

  • Install via npm:

    npm i pill
    

Usage

  1. Inject pill's <script> into page.
  2. Create content root element and give it id.
  3. Create loading indicator element.
  4. Initialize pill:
const loadingIndicator = document.querySelector('#indicator')

pill('#content', {
  onLoading() {
    // Show loading indicator
    loadingIndicator.style.display = 'initial'
  },
  onReady() {
    // Hide loading indicator
    loadingIndicator.style.display = 'none'
  }
})

Complete example

<html>
  <head>
    <title>Home</title>
    <script src="https://unpkg.com/pill@1/dist/pill.min.js"></script>
    <style>
      /* global styles */
      #indicator {
        position: fixed;
        top: 0;
        right: 0;
        display: none;
      }
    </style>
  </head>
  <body>
    <div id="indicator">Loading...</div>
    <div id="content">
      <style>/* page styles */</style>
      
      <!-- page content here -->
    </div>
    <script>
      const loadingIndicator = document.querySelector('#indicator')

      pill('#content', {
        onLoading() {
          // Show loading indicator
          indicator.style.display = 'initial'
        },
        onReady() {
          // Hide loading indicator
          indicator.style.display = 'none'
        }
      })
    </script>
  </body>
</html>

Each document of the site should surround #content element with the same HTML. All page-related content should be located inside #content. It could be styles, scripts, etc.

API

pill()

(selector:string, options:Options) -> void

Initialize pill. Start listening for navigation attempts and history state changes. Puts loaded content into selector element.

Options.onLoading()

(page:Page) -> void

Handle loading start.

Options.onReady()

(page:Page) -> void

Handle loading finish.

Options.fromError()

(error:Error) -> {title, content}

Use it to display notification when something went wrong. If an error was thrown while handling request. You still able to render content using method fromError

Options.shouldServe()

(url) -> boolean

Determine wither URL could be served by Pill. If returns false than link will be served by browser.

Options.shouldReload()

(page) => boolean

Determine wether previuosly loaded page should be loaded from server.

License

MIT © Rumkin

You can’t perform that action at this time.