KyleMit / eleventy-plugin-embed-tweet

A plugin for embedding tweets on the server side during build time
https://www.npmjs.com/package/eleventy-plugin-embed-tweet
25 stars 4 forks source link
eleventy eleventy-plugin twitter-api

Installation

Install on npm

npm install eleventy-plugin-embed-tweet --save

Add the following to your .eleventy.js config - see docs for options param:

module.exports = function(eleventyConfig) {

    const pluginEmbedTweet = require("eleventy-plugin-embed-tweet")
    eleventyConfig.addPlugin(pluginEmbedTweet);

};

Requirements

Requires signing up for free twitter developer API account - see docs for walkthrough

This plugin relies on making live API calls during build by using async shortcodes which were added in Eleventy v0.10.0 so it's listed as a peer dependency

Basic Usage

Embed a tweet anywhere you can use nunjucks templates using a shortcode with the tweet id like this:

Nunjucks

{% tweet "1188837207206977536" %}

Note: ID must be passed as a string because long numbers will truncate in JS)

Demo

Demo project available on github at KyleMit/eleventy-plugin-embed-tweet-demo and live version hosted on eleventy-embed-tweet.netlify.com/

Goals

Todo

Docs

Setting up Twitter Account

Setting .ENV variables

Once you sign up for a twitter account, you'll need to create a file named .env at the project root - it contains keys so it's excluded by the .gitignore so each person will have to manually create their own:

TOKEN=********
TOKEN_SECRET=********
CONSUMER_KEY=********
CONSUMER_SECRET=********

Remember to update your .gitignore with .env so you don't commit your secrets

You'll also have to add the environment variables on your build server.

If you build without setting environment variables, the API call won't work, so the plugin will fallback to using the client side embed available from publish.twitter.com

Plugin Options

let pluginEmbedTweet = require("eleventy-plugin-embed-tweet")

let tweetEmbedOptions = {
    cacheDirectory: '',    // default: ''
    useInlineStyles: true, // default: true
    autoEmbed: false       // default: false
}

eleventyConfig.addPlugin(pluginEmbedTweet, tweetEmbedOptions);

useInlineStyles

By default the single embed will contain all the necessary html and css to render each tweet. This occurs by including a <style> block along with the tweet. If you're embedding multiple tweets per page, you may elect to separate the CSS into it's own area so it's not repeated multiple times

You can instantiate the plugin like this:

eleventyConfig.addPlugin(pluginEmbedTweet, {useInlineStyles: false});

And then make sure to include the styles somewhere else on your page like this:

<style type="text/css">{% tweetStyles %}</style>

Feel free to also add your own styles and customize however you'd like. The official twitter widget is implemented as a web component and makes styling through the shadow dom really tricky - but this sits as flat html on your page - so customize however you'd like

The rough structure of the html returned by this plugin looks like this:

.tweet-card
    .tweet-header
        .tweet-profile
        .tweet-author
            .tweet-author-name
            .tweet-author-handle
        .tweet-bird
            .tweet-bird-icon
    .tweet-body
    .tweet-images
    .tweet-footer
        .tweet-like
            .tweet-like-icon.tweet-icon
            .tweet-like-count
        .tweet-date

cacheDirectory

Relying on an external, authenticated API to build your site has some tradeoffs:

To address these tradeoffs, this plugin can cache API calls locally which you can periodically commit to your repository.

To enable, you can pass a cacheDirctory path relative to your project root where you'd like to have data saved:

eleventyConfig.addPlugin(pluginEmbedTweet, {cacheDirectory: 'tweets'});

Because this directory will be updated during build time, you must add a .eleventyignore with the directories name, otherwise eleventy --serve can get stuck in an infinite loop when it detects changes and tries to rebuild the site during the build.

File: .eleventyignore

tweets/

I'd recommend periodically committing this file. The only data that'll change over time is the favorites_count, but otherwise you can have a relatively shelf stable set of data in your repository

If you'd like to guarantee that the build server is always getting the latest data for favorites_count, you can set CACHE_BUST=true in your build environment's variables or include in your scripts in you package.json like this:

"scripts": {
    "build": "npx eleventy",
    "serve": "npx eleventy --serve",
    "full-build": "set CACHE_BUST=true && npx eleventy",
    "clear-cache": "rm -rf tweets"
}

autoEmbed

This configuration option, if set to true, adds a transform to Eleventy to find links to tweets that are "alone" in a paragraph, with the value equal to the URL, and auto embed them, replacing the link.

For example:

<p><a href="https://twitter.com/KyleMitBTV/status/1211079569245114371">https://twitter.com/KyleMitBTV/status/1211079569245114371</a></p>

Will be replaced by the embedded tweet.

In the source Markdown, it only needs the tweet URL on one single line:


https://twitter.com/KyleMitBTV/status/1211079569245114371

Performance

Static site generators work hard to bake in performance and do as much work ahead of time as possible.

Which is why it's a bummer that the official way to embed tweets is to use the publish.twitter.com which looks like this:

<blockquote class="twitter-tweet">
  <p lang="en" dir="ltr">
    Nobody:<br><br>
    Software Marketing Page: &quot;Blazingly Fast&quot;
  </p>
  &mdash; Kyle Mitofsky (@KyleMitBTV)
  <a href="https://twitter.com/KyleMitBTV/status/1188837207206977536">October 28, 2019</a>
</blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

And performs like this:

twitter network traffic

// TODO - include real performance metrics/deltas