Choose Your Own Adventure

Presented by Brian Gershon


Problem at hand

  • Build a content site
  • Focus on progressive enhancement -- start with zero client-side JavaScript, and sprinkle on as needed
  • Support front-end experimentation without swapping frameworks: Vanilla JS, React, Svelte, Web Components

JAMstack seems perfect

Why JAMstack

JAMstack is client-side JavaScript + APIs + Markup

  • Generate whole site ahead of time for performance
  • Fast, easy hosting
  • Not dependent on a web/application server


My evolution of JAMstack tools over the years.

  • Jekyll (Ruby) for Github pages
  • Octopress (Ruby)
  • Hexo (JavaScript)
  • Currently using Eleventy and Gatsby

What about Gatsby?

A very nice JAMstack framework.

  • All data available via GraphQL
  • React and easy rehydration (server-side rendering + client interactivity)
  • Responsive images
  • Prefetch pages

Decisions for not using Gatsby

  • Was more than I needed (custom plug-ins, GraphQL normalization layer)
  • Whole site in one framework React + GraphQL
  • Required JavaScript to view base site (albeit not a deal breaker)
  • I do miss responsive images and prefetching (but you can build)

Needs vary

Gatsby may be perfect fit for you!

Why Eleventy?

"Eleventy facilitates JAMstack sites — but you maintain full control over the JavaScript."

  • Start small and add-on client-side JavaScript
  • Choice of template engines, including JavaScript templates
  • Use portable Vanilla JS as your plug-in system
  • Not a SPA, flexible to play with other tech

What's the gist?

Walk through a minimal Eleventy site.


Taking a Stroll

Walking through some real-life examples while creating briangershon.com site.

  • Add Blog
  • Working with data
  • Working with more data: Generating 10,000 pages from home-made Bookmark service

Adventure 1

Add blog

  • View a blog entry
  • Eleventy Collection tags
  • Blog listing page
  • Image cropping script

For blog listing, crop blog entry's 800 x 240 slice out. (generate-blog-slices.js)

            // sample extractParams:
            { left: 0, top: 0, width: 800, height: 240 }

            async function saveSliceToFS(inputPath, outputPath, extractParams) {
              return pipeline(
                  .resize(800, null, { withoutEnlargement: true })
                console.log(`Wrote (image) ${outputPath} with crop of ${JSON.stringify(extractParams)}`);

Adventure 2

Easily work with data

  • Plain ol' JSON for mock or real data (_data/siteData.js)
  • Upgrade to JavaScript for any data source (local files, REST, GraphQL, etc. (_data/bookmarks.js)

Adventure 3

10,000 Bookmarks / Pagination

  • Pagination (built-in)
  • Pagination (roll-my-own): Generate markdown, resize primary images (generate-bookmarks.js)

Built in pagination example

            layout: base.njk
              data: bookmarks.data
              size: 100
            title: Bookmarks


Interesting sites.


Issue: Initial deploy timed out

Netlify has time-limit on "deploy to CDN" step, so 10,000 pages/images timed out.

Workaround: Build 3,000 pages at a time. Netlify caching algo makes subsequent deploys fast.

Issue: Slower site generation

Generating 10,000 pages is quick (20 seconds), but ruins your watch experience elsewhere, like updating the blog.

Workaround: Add src/bookmarks to .eleventyignore

Enhancement Ideas

  • Support front-matter in Eleventy Pagination module (to avoid writing your own)
  • Add ability to --watch specific folders (instead of manually ignoring files)


Thank you

Presentation available at: