Eleventy

Choose Your Own Adventure

Presented by Brian Gershon

briangershon.com

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

JAMstacks

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."
https://www.11ty.dev/docs/

  • 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.

https://github.com/briangershon/eleventy-minimal

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(
                fs.createReadStream(inputPath),
                sharp()
                  .resize(800, null, { withoutEnlargement: true })
                  .extract(extractParams)
                  .jpeg(),
                fs.createWriteStream(outputPath)
              ).then(()=>{
                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
            pagination:
              data: bookmarks.data
              size: 100
            title: Bookmarks
            ---
            

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)

Resources

Thank you

Presentation available at:
https://www.briangershon.com/presents/eleventy-adventure/