<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Superfeedr Blog</title>
    <link href="https://superfeedr-blog-feed.herokuapp.com/" rel="self" type="application/atom+xml"/>
    <link href="http://blog.superfeedr.com/" rel="alternate" type="text/html"/>
    <link rel="hub" href="http://pubsubhubbub.superfeedr.com/" />
    <updated>2018-02-05T09:30:31-05:00</updated>
    <id>http://blog.superfeedr.com/</id>

    
    <entry>
        <title>Updated Pricing</title>
        
        <link href="http://blog.superfeedr.com/updated-pricing/"/>
        <published>2017-02-06T00:00:00-05:00</published>
        <updated>2017-02-06T00:00:00-05:00</updated>
        <id>blog.superfeedr.com:/updated-pricing</id>
        <summary>Our new pricing is based on the number of subscriptions that Superfeedr is handling for you. The first 10 feeds are always free.</summary>
        <content type="html">&lt;p&gt;Today, we are introducing a &lt;strong&gt;new pricing&lt;/strong&gt; for Superfeedr’s subscribers.&lt;/p&gt;

&lt;p&gt;In our early days, we wanted Superfeedr’s pricing to be based on the amount of data our service would send you. As we were very young start-up, we made the assumption that verbose feeds would cost us more to process and that it would be fair to pass this cost down to customers. In retrospect, this was not the best approach as it means that our pricing was less predictable than it should be: &lt;em&gt;subscribers do not control how verbose the feeds they’re subscribed to are&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As the &lt;a href=&quot;http://blog.superfeedr.com/google-feed-api-gone/&quot;&gt;Google Feed API is gone&lt;/a&gt;, a lot of our most recent customer are only using &lt;a href=&quot;http://blog.superfeedr.com/ways-to-use-superfeedr/&quot;&gt;our “pull” APIs&lt;/a&gt;. This means that they often have no visibility in the number of update for any given feed. This is another reason to reconsider our pricing.&lt;/p&gt;

&lt;p&gt;Our new approach is to charge our subscribers based on the number of feeds we process on their behalf. We analysed subscriber accounts and the recent invoices and came up with this beautiful scatter graph which allowed us to determine what would be the right breakdown.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://blog.superfeedr.com/images/price-per-subscription.png&quot; style=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And here are the rules we will be applying to all new subscriber accounts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;10 cts per subscription for the first 50 feeds,&lt;/li&gt;
  &lt;li&gt;5 cts for each feed up to 5,000 feeds,&lt;/li&gt;
  &lt;li&gt;2 cts for each feed up to 50,000 feeds,&lt;/li&gt;
  &lt;li&gt;1 ct per feed for each feed beyond that.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also use &lt;a href=&quot;https://superfeedr.com/subscriber#pricing&quot;&gt;our simulator&lt;/a&gt; for a more detailed estimation.&lt;/p&gt;

&lt;p&gt;Additionally, if your invoice is less than $1, we will waive it; this means that the &lt;strong&gt;first 10 feeds are always free&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Finally, even though this pricing should almost always mean lower invoices for our existing customers, we offer them the ability to remain on the current pricing for as long as they want.&lt;/p&gt;

</content>
        <author>
            <name>Julien</name>
            <uri>http://ouvre-boite.com</uri>
        </author>
    </entry>
    
    <entry>
        <title>Google Feed API is gone: now what?</title>
        
        <link href="http://blog.superfeedr.com/google-feed-api-gone/"/>
        <published>2016-12-12T00:00:00-05:00</published>
        <updated>2016-12-12T00:00:00-05:00</updated>
        <id>blog.superfeedr.com:/google-feed-api-gone</id>
        <summary>Switch to Superfeedr for the API and Embedly for the embeds.</summary>
        <content type="html">&lt;p&gt;As you &lt;a href=&quot;https://blog.superfeedr.com/google-feed-api-alternative/&quot;&gt;might have heard&lt;/a&gt;, the &lt;strong&gt;Google Feed API&lt;/strong&gt; is closing on December 15th, 2016. It’s not too late to look for a replacement and Superfeedr has you covered, either directly, or via Embedly.&lt;/p&gt;

&lt;p&gt;The Google Feed API was used to build all types of  applications, from simple web page embeds to more advanced feed readers and podcasts players. &lt;a href=&quot;https://superfeedr.com&quot;&gt;Superfeedr&lt;/a&gt; is a powerful replacement which also provides tools for all of these use cases. We also have solutions for feed &lt;a href=&quot;https://superfeedr.com/publisher&quot;&gt;publishers&lt;/a&gt; or even for people looking for &lt;a href=&quot;https://superfeedr.com/tracker&quot;&gt;real-time search filters&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Compared to the Google Feed API, we provide a &lt;a href=&quot;http://documentation.superfeedr.com/schema.html&quot;&gt;richer schema&lt;/a&gt; (with &lt;a href=&quot;https://blog.superfeedr.com/more-metadata/&quot;&gt;more metadata&lt;/a&gt;!).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;push-vspull&quot;&gt;Push vs. Pull&lt;/h2&gt;

&lt;p&gt;One of the largest benefits of using Superfeedr’s infrastructure is that rather than polling data from us, you can &lt;strong&gt;subscribe&lt;/strong&gt; to the feeds and be notified using &lt;strong&gt;webhooks&lt;/strong&gt; when these are updated. That means you do not have to load data from Superfeedr on your web pages, but can conveniently store it on your server and serve it from there.&lt;/p&gt;

&lt;h2 id=&quot;embedding-feeds&quot;&gt;Embedding feeds&lt;/h2&gt;

&lt;p&gt;In addition to consuming feeds, if you’re looking to &lt;em&gt;embed feeds&lt;/em&gt;, consider using &lt;a href=&quot;http://embed.ly/&quot;&gt;Embedly&lt;/a&gt;. Embedly is a Superfeedr customer and the processing of feeds is handled transparently by us.&lt;/p&gt;

&lt;p&gt;Their embed is very simple to configure and is responsive which means it will look great on both desktop and mobile web. Here’s an example with the feed for &lt;a href=&quot;https://blog.superfeedr.com/&quot;&gt;this blog&lt;/a&gt; (you can replace the value of the &lt;code&gt;href&lt;/code&gt; attribute with any feed):&lt;/p&gt;

&lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;a class=&amp;quot;embedly-card&amp;quot; href=&amp;quot;https://superfeedr-blog-feed.herokuapp.com/&amp;quot;&amp;gt;Feed&amp;lt;/a&amp;gt;
&amp;lt;script async src=&amp;quot;//cdn.embedly.com/widgets/platform.js&amp;quot; charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And here is the output:&lt;/p&gt;

&lt;p&gt;&lt;a class=&quot;embedly-card&quot; href=&quot;https://superfeedr-blog-feed.herokuapp.com/&quot;&gt;Feed&lt;/a&gt;
&lt;script async=&quot;&quot; src=&quot;http://blog.superfeedr.com//cdn.embedly.com/widgets/platform.js&quot; charset=&quot;UTF-8&quot;&gt;&lt;/script&gt;&lt;/p&gt;

</content>
        <author>
            <name>Julien</name>
            <uri>http://ouvre-boite.com</uri>
        </author>
    </entry>
    
    <entry>
        <title>Building a News Bot for Facebook Messenger</title>
        
        <link href="http://blog.superfeedr.com/news-bot-rss-facebook-messenger/"/>
        <published>2016-11-01T00:00:00-04:00</published>
        <updated>2016-11-01T00:00:00-04:00</updated>
        <id>blog.superfeedr.com:/news-bot-rss-facebook-messenger</id>
        <summary>We built a news bot Facebook Messenger which lets you follow you favorite websites and be notified when they publish new stories.</summary>
        <content type="html">&lt;p&gt;With each month that goes by, there is less and less doubt that messaging applications and bots are one of the interfaces with whom we are interacting more and more. One of the verticals for which messaging applications are the most useful is news.&lt;/p&gt;

&lt;p&gt;We built a news bot Facebook Messenger which lets you follow you favorite websites and be notified when they publish new stories.&lt;/p&gt;

&lt;h2 id=&quot;try-it-first&quot;&gt;Try it first&lt;/h2&gt;

&lt;p&gt;If you have a Facebook account, you should start by testing the news bot to see what it’s capable of. It’s as easy as &lt;a href=&quot;https://m.me/superfeedr&quot;&gt;opening this link&lt;/a&gt;. You should now be able to start a conversation with Superfeedr’s bot. First I usually say &lt;em&gt;Hello&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The bots let you then type (or paste really), the URL of your favorite site. I chose &lt;a href=&quot;https://medium.com/superfeedr-thoughts&quot;&gt;Superfeedr’s Medium publication&lt;/a&gt; so I typed &lt;code&gt;http://medium.com/superfeedr-thoughts&lt;/code&gt;. The bot then uses &lt;a href=&quot;http://feediscovery.appspot.com/&quot;&gt;Feediscovery&lt;/a&gt; to find an relevant RSS feed and asks for a final confirmation. Once this is all set, the next time the publication publishes something, you should get a message from the bot to read that story.&lt;/p&gt;

&lt;p&gt;This is a pretty simple bot but already does wonders!&lt;/p&gt;

&lt;h2 id=&quot;how-we-built-it&quot;&gt;How we built it&lt;/h2&gt;

&lt;p&gt;The quick answer is that we took the exact same code base that we used for &lt;a href=&quot;https://blog.superfeedr.com/rss-bot-telegram-lambda/&quot;&gt;Telegram bot we built last year&lt;/a&gt;. It also runs on Amazon’s Lambda infrastructure which, even if it is complex to set up is &lt;strong&gt;perfect of webhook based services&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The whole bot code is &lt;a href=&quot;https://github.com/superfeedr/news-bot&quot;&gt;available on Github&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;setting-things-up-on-facebook&quot;&gt;Setting things up on Facebook.&lt;/h3&gt;

&lt;p&gt;First, we have to &lt;a href=&quot;https://developers.facebook.com/&quot;&gt;build a Facebook application&lt;/a&gt;. You also need a Facebook page as Facebook’s Messenger bots are linked to a page.&lt;/p&gt;

&lt;p&gt;Switch to the Messenger settings and start by generating a token that you’ll use to send requests to the Facebook API. For this, you need to select  the page that users will interact with. Copy this token to the settings &lt;a href=&quot;https://github.com/superfeedr/news-bot/blob/master/src/_init.js&quot;&gt;in the &lt;code&gt;init&lt;/code&gt; file&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://blog.superfeedr.com/images/facebook-news-bot/token-generation.png&quot; alt=&quot;Generate Token&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then, you have to configure the webhooks for incoming messages.&lt;/p&gt;

&lt;p&gt;The base URL is where our service will be deployed (you should use an Amazon Lambda URL if you’re deploying your bot there). Our code routes incoming webhooks using the &lt;code&gt;platform&lt;/code&gt; query string parameter.&lt;/p&gt;

&lt;p&gt;We also specify the types of messages we want to receive: &lt;code&gt;message_deliveries&lt;/code&gt;, &lt;code&gt;messages&lt;/code&gt;, &lt;code&gt;messaging_optins&lt;/code&gt;, &lt;code&gt;messaging_postbacks&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Facebook will send a verification of intent request (PubSubHubbub FTW!) and you should set a random verification token: the bot’s code should handle that by default.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://blog.superfeedr.com/images/facebook-news-bot/facebook-webhooks-settings.png&quot; alt=&quot;Webhook Settings&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After that you should be all set.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Feel free to follow the &lt;a href=&quot;https://developers.facebook.com/docs/messenger-platform/guides/quick-start&quot;&gt;quick start instructions&lt;/a&gt; in Facebook’s docs for more details.&lt;/small&gt;&lt;/p&gt;

&lt;h3 id=&quot;architecture-overview&quot;&gt;Architecture overview&lt;/h3&gt;

&lt;p&gt;The news bot code is routing incoming events based on the &lt;code&gt;platform&lt;/code&gt; query string value. Each message is sent to the right platform handler to be parsed. Each of these platform handlers (Facebook and Telegram for now) implements a &lt;code&gt;parseChatMessage&lt;/code&gt; method which yields back to the main router.&lt;/p&gt;

&lt;p&gt;The main router then identifies the command. We currently support the following commands: &lt;em&gt;hello&lt;/em&gt;, &lt;em&gt;help&lt;/em&gt;, &lt;em&gt;list&lt;/em&gt;, &lt;em&gt;subscribe&lt;/em&gt;, &lt;em&gt;unsubscribe&lt;/em&gt;, &lt;em&gt;url&lt;/em&gt; and &lt;em&gt;version&lt;/em&gt;. Once they have been executed; they themselves call the platforms to send back messages to users. By using this, we can let &lt;strong&gt;each platform implement its own specific features&lt;/strong&gt;, such as buttons or custom keyboards.&lt;/p&gt;

&lt;p&gt;When a user starts to follow a feed, we issue a &lt;a href=&quot;https://documentation.superfeedr.com/subscribers.html#adding-feeds-with-pubsubhubbub&quot;&gt;subscription request to Superfeedr&lt;/a&gt;. The callback URL used for these subscriptions includes the &lt;code&gt;platform&lt;/code&gt; as well as a unique &lt;code&gt;chatId&lt;/code&gt; to identify the exact user who should receive the data. By doing this, we &lt;strong&gt;do not have to store any state inside our bot&lt;/strong&gt;, making the webhook pattern trivial to scale.&lt;/p&gt;

&lt;p&gt;Finally, when Superfeedr sends a notification to the news bot, we extract the platform and chat id from the callback URL, as well as the content of the message and invoke the platform’s &lt;code&gt;sendMessage&lt;/code&gt; method.&lt;/p&gt;

&lt;h3 id=&quot;the-future&quot;&gt;The future&lt;/h3&gt;

&lt;p&gt;Adding support for more platforms such as Slack or Kik should be fairly simple. We could also start adding more commands such as &lt;code&gt;track&lt;/code&gt; to implement the &lt;a href=&quot;https://documentation.superfeedr.com/trackers.html&quot;&gt;tracker capabilities of Superfeedr&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please, let us know what you think! You’re more than welcome to fork the code!&lt;/p&gt;
</content>
        <author>
            <name>Julien</name>
            <uri>http://ouvre-boite.com</uri>
        </author>
    </entry>
    
    <entry>
        <title>Medium acquires Superfeedr</title>
        
        <link href="http://blog.superfeedr.com/medium-acquires-superfeedr/"/>
        <published>2016-06-02T00:00:00-04:00</published>
        <updated>2016-06-02T00:00:00-04:00</updated>
        <id>blog.superfeedr.com:/medium-acquires-superfeedr</id>
        <summary>Publishing on the web is changing drastically. Medium is one of these few companies which are building the future of publishing and reading. We&#39;re excited to join forces with them and continue building the open web in this new era!</summary>
        <content type="html">&lt;p&gt;The web is very different from what it was 8 years ago. We’ve &lt;a href=&quot;https://blog.superfeedr.com/instant-articles-future-rss/&quot;&gt;said it&lt;/a&gt; &lt;a href=&quot;https://blog.superfeedr.com/apple-facebook-rss/&quot;&gt;several&lt;/a&gt; &lt;a href=&quot;https://blog.superfeedr.com/it-is-called-rss/&quot;&gt;times&lt;/a&gt;: publishing and consuming content are &lt;strong&gt;new frontiers&lt;/strong&gt; for most of the web giants like Facebook, Google or Apple. We consume the web from mobile devices, we discover content on silo-ed social networks and, more importantly, the base metaphor for &lt;a href=&quot;http://www.ouvre-boite.com/space-to-time/&quot;&gt;the web is shifting from “space” to “time”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://superfeedr.com&quot;&gt;Superfeedr&lt;/a&gt;, the &lt;strong&gt;open web’s leading feed API&lt;/strong&gt; and PubSubHubbub hub has been an independent player for 8 years. Superfeedr exists in order to enable people to exchange information on the web more freely and easily. Today, we’re excited to announce Superfeedr has been acquired by &lt;a href=&quot;https://medium.com&quot;&gt;Medium&lt;/a&gt;. In many ways, it’s a very natural fit: Medium wants to create the best place to publish, distribute and consume content on the web. Together, we are hoping to keep Medium the company a leader in good industry practices, and Medium the network a place where this conversation can gain even more traction.&lt;/p&gt;

&lt;p&gt;At Superfeedr, we’ve promoted the open web by embracing open formats and protocols, such as RSS, Atom, XMPP and PubSubHubbub. Over the years, we’ve also learned that these protocols are only as powerful as the people who promote them. As we want the open web to remain strong, we were delighted to find that the folks at Medium share the same values. And we think that Superfeedr’s acquisition is a powerful indicator of Medium’s support for open protocols. As an example of this, my first commit at Medium was to enable full content RSS feeds both for publications and users (available &lt;a href=&quot;https://medium.com/me/settings&quot;&gt;in your settings&lt;/a&gt;). Medium already lets you add your own domain name, import and export all of your posts, point to a canonical URL if you cross-posted, supports DNT… and we’ve started working on more!&lt;/p&gt;

&lt;p&gt;If you are a Superfeedr customer, &lt;strong&gt;nothing has changed&lt;/strong&gt;: it’s business as usual. More than ever, we are dedicated to providing you with a convenient way to &lt;em&gt;consume&lt;/em&gt; or &lt;em&gt;publish feeds&lt;/em&gt; from all over the web using open protocols as well as &lt;a href=&quot;https://superfeedr.com/tracker&quot;&gt;tracking keywords in real time&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally, I also want to take a couple moments to thank all the Superfeedr family: the numerous contractors with whom we’ve worked over the years, our investors (&lt;a href=&quot;https://betaworks.com&quot;&gt;Betaworks&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/mcuban&quot;&gt;Mark Cuban&lt;/a&gt;), as well as our advisors and partners.&lt;/p&gt;

&lt;p&gt;I’m confident Medium is the right home for Superfeedr. The team here is one of the most talented I’ve ever met and we’re already leading the way when it comes to enabling amazing content publishing. Every month, people collectively spend 2,000,000 hours reading these stories, and I’m delighted to be part of the team building this!&lt;/p&gt;

</content>
        <author>
            <name>Julien</name>
            <uri>http://ouvre-boite.com</uri>
        </author>
    </entry>
    
    <entry>
        <title>Focus on the Front-End: Building an Asset Repository</title>
        
        <link href="http://blog.superfeedr.com/new-assets/"/>
        <published>2016-04-05T00:00:00-04:00</published>
        <updated>2016-04-05T00:00:00-04:00</updated>
        <id>blog.superfeedr.com:/new-assets</id>
        <summary>Change is afoot in Superfeedr’s websites—change in the form of patterns, centralization, and standardization.</summary>
        <content type="html">&lt;p&gt;Change is afoot in Superfeedr’s websites—change in the form of patterns, centralization, and standardization.&lt;/p&gt;

&lt;p&gt;In the summer of 2014, a team from &lt;a href=&quot;https://www.vanpattenmedia.com/&quot;&gt;Van Patten Media Inc.&lt;/a&gt;—in this case, &lt;a href=&quot;http://www.chrisvanpatten.com&quot;&gt;Chris Van Patten&lt;/a&gt; and &lt;a href=&quot;http://lucascherkewski.com&quot;&gt;myself&lt;/a&gt;—worked with Julien here at Superfeedr to &lt;a href=&quot;https://blog.superfeedr.com/new-design/&quot;&gt;redesign the application’s web interface&lt;/a&gt;. We updated a dated design, surfacing functionality that was previously hidden, and made it easier for people new to Superfeedr to figure out just how great it is. The Van Patten Media team also worked on the public-facing elements of the website, redesigning the marketing site, documentation, and blog from the ground up.&lt;/p&gt;

&lt;p&gt;We were happy with the results of these redesign projects, and were excited at the opportunity to work with Julien again on a new project: developing a centralized asset repository and pattern library for all Superfeedr web properties.&lt;/p&gt;

&lt;h2 id=&quot;project-goals&quot;&gt;Project goals&lt;/h2&gt;

&lt;p&gt;We had a few key goals with this latest project:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Develop a repository that all properties could pull from, centrally-updated so that improvements were shared;&lt;/li&gt;
  &lt;li&gt;Cut down on redundancy and push for more consistency across the interfaces;&lt;/li&gt;
  &lt;li&gt;Document all the patterns in use across Superfeedr’s various sites;&lt;/li&gt;
  &lt;li&gt;Make it easier to design new pages or properties in the future.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’re happy to say that, after a few weeks of work, we’ve accomplished these goals! With all these new changes, there are a few in particular that we want to highlight and dig into a little further.&lt;/p&gt;

&lt;h2 id=&quot;patterns-patterns-patterns&quot;&gt;Patterns, patterns, patterns&lt;/h2&gt;

&lt;p&gt;Whether you call it a pattern library or a style guide, this method of development and documentation has increased in popularity over the last few years, and for good reason: it encourages and rewards modular thinking in terms of markup, styles, and functionality for front-end components.&lt;/p&gt;

&lt;p&gt;When we set out on our initial redesign of Superfeedr back in in 2014, our first code took place in a small &lt;code&gt;patterns.html&lt;/code&gt; file. We didn’t set out to create a proper “pattern library” on day one, but having this file made it easier to see a collection of components in one place and, as we started to design full pages, simplified the work by letting us copy and paste.&lt;/p&gt;

&lt;p&gt;This initial, informal pattern library was brought out again as we started working on this most recent project. Because a key goal for the project was to create a “centralised repo” for our assets, we knew we’d have to combine stylesheets from a few sources. A structured, formal pattern library would help prevent us from missing key modules or duplicating code as we merged the assets into one canonical source.&lt;/p&gt;

&lt;p&gt;We evaluated a number of open source pattern documentation tools, but eventually landed on a custom approach. We gave each pattern its own HTML file, and loaded each one into an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; in the final output via a build process powered by &lt;a href=&quot;https://github.com/coderhaoxin/gulp-file-include&quot;&gt;&lt;code&gt;gulp-file-include&lt;/code&gt;&lt;/a&gt;, using the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-srcdoc&quot;&gt;&lt;code&gt;srcdoc&lt;/code&gt;&lt;/a&gt; attribute. This ensured that each pattern could function in isolation, unaffected by other modules or the pattern library itself.&lt;/p&gt;

&lt;p&gt;We also added a brief description and usage notes for each pattern, so that anyone looking to extend Superfeedr in the future could easily understand which patterns to use, and how. We built, in essence, &lt;a href=&quot;http://daverupert.com/2013/04/responsive-deliverables/#tiny-bootstraps-for-every-client&quot;&gt;a tiny Bootstrap&lt;/a&gt; for Superfeedr’s use—and you can &lt;a href=&quot;https://assets.superfeedr.com&quot;&gt;view it yourself, too!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Making this pattern library helped us find parts of the design that were redundant, buggy, or less than ideal, and fix them to a known-good standard—fitting, given Superfeedr’s huge support for standards-based applications! Even though Superfeedr is just one entity, its four properties now stand that much more unified thanks to the documentation and implementation of these patterns, and any future expansions of the service can be quickly designed and implemented.&lt;/p&gt;

&lt;h2 id=&quot;bootstrap-compatibility&quot;&gt;Bootstrap compatibility&lt;/h2&gt;

&lt;p&gt;When Julien developed &lt;a href=&quot;https://blog.superfeedr.com/river-news/&quot;&gt;river.news&lt;/a&gt;, he wanted to show off Superfeedr’s capabilities in an application that could be plugged into many websites and just work. When he did this, he styled the markup with Bootstrap classes, knowing that many websites use Bootstrap, so that if River.news was embedded on a site already using Bootstrap, it’d look great. However, he also wanted code styled with Bootstrap classes displayed on a Superfeedr property to look and feel like Superfeedr.&lt;/p&gt;

&lt;p&gt;After evaluating a few options, and some conceptual tug-of-war as we tried to determine the most efficient way to do this, we settled on Sass &lt;a href=&quot;http://sass-lang.com/guide#topic-7&quot;&gt;&lt;code&gt;@extend&lt;/code&gt;s&lt;/a&gt;, which allow you to apply the styles from one CSS rule to another.&lt;/p&gt;

&lt;p&gt;For example, here’s how we mapped Bootstrap’s inimitable button classes:&lt;/p&gt;

&lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;.btn {
  @extend .button;
}

  .btn-default,
  .btn-info,
  .btn-primary,
  .btn-success,
  .btn-warning,
  .btn-danger {
    @extend .button--raised;
  }

  .btn-default,
  .btn-info {
    @extend .button--neutral;
  }

  .btn-primary,
  .btn-success {
    @extend .button--positive;
  }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;…and so on.&lt;/p&gt;

&lt;p&gt;As you can see, we were able to avoid duplicating the actual rules by mapping our existing styles to the Bootstrap class names.&lt;/p&gt;

&lt;p&gt;As we worked on this feature, we had a number of discussions (between ourselves and with Julien) about this particular requirement. It’s an interesting challenge: how do you make an embeddable module look “native” in as many contexts as possible? We settled on this Bootstrap “map”, but there are other approaches as well. We like the look of &lt;a href=&quot;http://glenmaddern.com/articles/css-modules&quot;&gt;CSS modules&lt;/a&gt;, which allow you to automatically namespace and modularise CSS within a given widget. CSS modules are designed for large CSS codebases, but could also allow projects like River.news to provide “mappings” to frameworks like Bootstrap or Foundation, and allow users to swap between them without requiring multiple sets of markup. It would also make it easier for users to provide custom CSS that fits within their unique design.&lt;/p&gt;

&lt;p&gt;We also realised the importance of good documentation of classes and markup. Even if not using a standardized CSS class structure—like BEM, OOCSS, SMACSS, or so on—adopting standard conventions for HTML structure and class names in your project can make it easier for others to adapt your work to their particular use case, without needing to fork it or reinvent the wheel.&lt;/p&gt;

&lt;p&gt;Markup underlies all the work we do on the web, and being sensible about its form will go a long way towards increasing the interoperability of our various components.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;It has been a thrill to work with Julien on a service that’s so important to so many organisations and projects around the web. Superfeedr stands for open protocols, open software, and open communications—which is why we were so excited to write this post and document our efforts.&lt;/p&gt;

&lt;p&gt;Working with Julien on Superfeedr has been a fantastic experience, and we’re proud of the results of this project: we created a pattern library and central assets repository that drives all of the Superfeedr web properties, and will make it much easier to update them or make new ones in the future. We’re excited to see where Julien takes Superfeedr next!&lt;/p&gt;
</content>
        <author>
            <name>Lucas</name>
            <uri>http://lucascherkewski.com</uri>
        </author>
    </entry>
    
    <entry>
        <title>Embed and customize River.news </title>
        
        <link href="http://blog.superfeedr.com/embed-river-news/"/>
        <published>2016-03-30T00:00:00-04:00</published>
        <updated>2016-03-30T00:00:00-04:00</updated>
        <id>blog.superfeedr.com:/embed-river-news</id>
        <summary>River.news is a very basic feed reader which can be embedded on any we page</summary>
        <content type="html">&lt;p&gt;The &lt;a href=&quot;https://superfeedr.com/&quot;&gt;superfeedr feed API&lt;/a&gt; is quite powerful and lets anyone build any kind of application which consumes RSS feeds, whether it’s on the web, a mobile application, or processed on the server side. Building and maintaining servers is not always trivial, which is why more and more applications are built to be server-less. This is the case of our &lt;a href=&quot;https://river.news&quot;&gt;river.news&lt;/a&gt; app. We recently updated it and here’s a breakdown of what it does.&lt;/p&gt;

&lt;p&gt;Not only you can use &lt;a href=&quot;https://river.news&quot;&gt;River.news&lt;/a&gt; on its own domain, but you can also effortlessly embed on any HTML page… &lt;a href=&quot;#rivernews&quot;&gt;like this one&lt;/a&gt;:&lt;/p&gt;

&lt;h2 id=&quot;offline-service-workers&quot;&gt;Offline: Service Workers&lt;/h2&gt;

&lt;p&gt;If you read this blog often, you’ve already seen that &lt;a href=&quot;https://blog.superfeedr.com/service-workers/&quot;&gt;we added offline support to river.news&lt;/a&gt;. Service Workers are completely changing the web from a document-oriented architecture (HTML pages are loaded first) to an &lt;strong&gt;application-oriented architecture&lt;/strong&gt; with javascript executed even before HTTP requests are fired.&lt;/p&gt;

&lt;h2 id=&quot;better-styling&quot;&gt;Better styling&lt;/h2&gt;

&lt;p&gt;Recently, we centralised all of our styling assets on &lt;a href=&quot;https://assets.superfeedr.com/&quot;&gt;assets.superfeedr.com&lt;/a&gt;. The fantastic team at &lt;a href=&quot;https://www.vanpattenmedia.com/&quot;&gt;Van Patten Media&lt;/a&gt; did an amazing work to group, document and simplify all the assets used by Superfeedr. Our river.news now uses these assets by default. Also, since we use the bootstrap classes, including Bootstrap’s CSS will yield a nice looking style to your instance of river.news!&lt;/p&gt;

&lt;h2 id=&quot;customisable&quot;&gt;Customisable&lt;/h2&gt;

&lt;p&gt;Finally, the most recent version of river.news lets you hard-code a login and token. You can also prevent the visitor from changing the subscription list. For example, the river embedded above has disable the ability to enter a superfeedr login and password, as well as the ability to subscribe to new feeds. The configuration happens in the DOM, with &lt;code&gt;data-attributes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There’s a lot more to do! What features are important to you in an embeddable feed reader?&lt;/p&gt;

&lt;div id=&quot;rivernews&quot; data-superfeedr-login=&quot;superfeedr&quot; data-superfeedr-token=&quot;1a8c661804873703802212503e75d3c2&quot; data-disable-settings=&quot;&quot; data-disable-subscriptions=&quot;&quot;&gt;&lt;/div&gt;
</content>
        <author>
            <name>Julien</name>
            <uri>http://ouvre-boite.com</uri>
        </author>
    </entry>
    
    <entry>
        <title>Instant Articles and the future of RSS</title>
        
        <link href="http://blog.superfeedr.com/instant-articles-future-rss/"/>
        <published>2016-03-01T00:00:00-05:00</published>
        <updated>2016-03-01T00:00:00-05:00</updated>
        <id>blog.superfeedr.com:/instant-articles-future-rss</id>
        <summary></summary>
        <content type="html">&lt;p&gt;In the past couple months, a lot has been happening on the &lt;em&gt;syndication&lt;/em&gt; front. The mobile and social worlds have become more and more aware of the importance of the &lt;strong&gt;open web&lt;/strong&gt; and we’ve seen several new efforts to improve the user experience on these fronts.&lt;/p&gt;

&lt;h2 id=&quot;mobile&quot;&gt;Mobile&lt;/h2&gt;

&lt;p&gt;Despite increasing bandwidth, the constraints of the mobile internet are still extremely tight: latency, spotty connections, limited memory and power… etc. The &lt;a href=&quot;http://idlewords.com/talks/website_obesity.htm&quot;&gt;web’s constant growth&lt;/a&gt; when it comes to page size, number of loaded resources and the need for more and more beams and advertisement have been colliding with this.&lt;/p&gt;

&lt;h2 id=&quot;social&quot;&gt;Social&lt;/h2&gt;

&lt;p&gt;In parallel, more than ever, we discover our content through the filter of the social networks. A couple months ago, our friends at Parsely shared that &lt;a href=&quot;https://blog.parsely.com/post/2296/facebook-dominates-referral-traffic-a-coverage-overview/&quot;&gt;Facebook was dominating the referral traffic&lt;/a&gt;. The actual mileage varies from site to site, but it’s obvious that the golden days of SEO and search-engine based discovery are behind us.&lt;/p&gt;

&lt;h2 id=&quot;space-vs-time&quot;&gt;Space vs. Time&lt;/h2&gt;

&lt;p&gt;Another, more massive trend is supported by these 2: the &lt;a href=&quot;http://www.ouvre-boite.com/space-to-time/&quot;&gt;web is going toward a spatial organisation toward a time-based organization&lt;/a&gt;: time-lines have replaced site-maps and URLs are slowly being hidden from the user interfaces: where we consume the content is less important than what it was.&lt;/p&gt;

&lt;h2 id=&quot;syndication-rebooted&quot;&gt;Syndication rebooted&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://instantarticles.fb.com/&quot;&gt;Instant Articles&lt;/a&gt; are Facebook’s answer to these trends. (So is &lt;a href=&quot;https://www.ampproject.org/&quot;&gt;Google’s AMP&lt;/a&gt;). In practice, these HTML documents are &lt;strong&gt;embedded inside RSS feeds&lt;/strong&gt; so that Facebook can easily import the web’s content into its apps. Like RSS, they’re &lt;em&gt;not as rich as full HTML document&lt;/em&gt;. For example, they can’t include scripts or styles. They also require a certain number of elements which would be optional with HTML.&lt;/p&gt;

&lt;p&gt;On their end, Facebook will &lt;strong&gt;replicate&lt;/strong&gt; the content of the publisher’s site, using the Instant Article format. Each open web URL is mapped to an Instant Article inside Facebook. This is what lets them serve content much faster as they are in charge of caching and content delivery. The consequence of this approach is that once a publisher starts supporting Instant Articles, Facebook will show the Instant Article version of the content &lt;strong&gt;as soon as anyone shares a link to this site&lt;/strong&gt;. You don’t have to share the links from a Facebook page : any link to the content will be served as its Instant Article version.&lt;/p&gt;

&lt;p&gt;Some may be scared by this which results in building a &lt;strong&gt;shadow web&lt;/strong&gt;, inside Facebook, but I’d like to to highlight a couple things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;This is exactly how RSS has worked since it was conceived&lt;/li&gt;
  &lt;li&gt;This is also how &lt;a href=&quot;https://www.ampproject.org/&quot;&gt;Google’s AMP&lt;/a&gt; work except that of course, in this case, Google’s cache is applied&lt;/li&gt;
  &lt;li&gt;Anyone, not just Facebook, could also cache the Instant Article version of the pages shared on their platform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You guessed it: at &lt;a href=&quot;https://superfeedr.com&quot;&gt;Superfeedr&lt;/a&gt;, we’re evaluating this final and last point. Exactly &lt;a href=&quot;http://blog.superfeedr.com/bridging-amp-and-rss/&quot;&gt;like for Google’s AMP&lt;/a&gt;, we’re working on supporting Facebook’s Instant Article as a subscription format so that when you subscribe to a feed, you could request to only be notified with the Instant Article version of content, if it’s available.&lt;/p&gt;

</content>
        <author>
            <name>Julien</name>
            <uri>http://ouvre-boite.com</uri>
        </author>
    </entry>
    
    <entry>
        <title>Full Text RSS</title>
        
        <link href="http://blog.superfeedr.com/full-text-rss/"/>
        <published>2016-01-28T00:00:00-05:00</published>
        <updated>2016-01-28T00:00:00-05:00</updated>
        <id>blog.superfeedr.com:/full-text-rss</id>
        <summary>Truncating RSS feeds is probably the worse a publisher can do: it degrades the experience of savvy users who chose to follow the RSS feed.</summary>
        <content type="html">&lt;p&gt;Of course, if your website publishes content, you should &lt;strong&gt;absolutely publish RSS feeds&lt;/strong&gt; (or Atom feeds, &lt;a href=&quot;http://blog.superfeedr.com/gospel/feeds/atom-or-rss-not-both/&quot;&gt;but not both&lt;/a&gt;!). Luckily, a lot of publishers eventually do, even if they sometimes have trouble dealing with &lt;a href=&quot;http://blog.superfeedr.com/rss-autodiscovery/&quot;&gt;auto-discovery&lt;/a&gt;. However, a lot of these publishers will publish &lt;em&gt;truncated&lt;/em&gt; RSS feeds, and that’s generally a bad idea.&lt;/p&gt;

&lt;p&gt;The main reason publishers truncate their feeds is that they expect the subscribers want to visit the “original” site and then view its ads or interact with the content more… Other publishers fear that full text RSS feeds can be used by scrapers to duplicate content and rank better in search engine. Let’s face it: if somebody wants to duplicate content, there are many more ways than using the RSS feeds.&lt;/p&gt;

&lt;h2 id=&quot;who-uses-rss-feeds&quot;&gt;Who uses RSS feeds?&lt;/h2&gt;

&lt;p&gt;These days, it’s clear that &lt;strong&gt;RSS is mostly used by advanced users&lt;/strong&gt;: &lt;a href=&quot;http://www.businessinsider.com/feedly-2014-2?IR=T&quot;&gt;millions of of them&lt;/a&gt;, but still a small fraction of the &lt;a href=&quot;http://www.internetlivestats.com/internet-users/&quot;&gt;web’s 3+ Bn users&lt;/a&gt;. Given the relative complexity of most feed readers when compared to the social web applications, it’s also safe to assume that these users are at least savvy.&lt;/p&gt;

&lt;p&gt;When it comes to ads, the most savvy web users are often the ones who use ad-blockers. Even when they don’t, they also tend to click less on these banners. So, chances are that &lt;em&gt;even if they clicked&lt;/em&gt; in their readers to view the rest of the truncated content, they &lt;strong&gt;won’t even see or click on the ads&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s also important to remember that feed reader users &lt;strong&gt;chose&lt;/strong&gt; to use a feed reader (many of them actually pay to use the feed reader of their choice). They understand their limitations as well as their benefits. It’s certainly much harder than expected to entice them to click on links &lt;em&gt;away&lt;/em&gt; from their readers.&lt;/p&gt;

&lt;h2 id=&quot;the-feed-readers-are-good&quot;&gt;The feed readers are good!&lt;/h2&gt;

&lt;p&gt;Often, feed readers are &lt;strong&gt;offline first&lt;/strong&gt; experiences: they aggregate content from multiple sources so that the data can be consumed while commuting, on planes… but more importantly (and more often), the feed reader users &lt;em&gt;don’t have to wait for the data to load&lt;/em&gt; for each entry that they’re reading. Generally, feed readers will be able to load all recent stories at once, allowing for a much faster experience when reading story after story.&lt;/p&gt;

&lt;p&gt;These days, modern feed readers &lt;em&gt;also include a lot of social web features&lt;/em&gt; which let their users share the feed’s content, favorite the stories they like the most, and more. By doing this, the feed readers can drive a lot of traffic back to the publisher’s site.&lt;/p&gt;

&lt;p&gt;Finally, &lt;strong&gt;degrading the experience can sometimes be worse than not providing any RSS feed at all&lt;/strong&gt;. These advanced users are certainly very experienced and are also influential. If their experience interacting with the publisher’s content is great, they’re more likely to more of consume it and share it even more.&lt;/p&gt;
</content>
        <author>
            <name>Julien</name>
            <uri>http://ouvre-boite.com</uri>
        </author>
    </entry>
    
    <entry>
        <title>Hijacking API requests with Service Workers</title>
        
        <link href="http://blog.superfeedr.com/hijacking-api-requests-service-worker/"/>
        <published>2016-01-20T00:00:00-05:00</published>
        <updated>2016-01-20T00:00:00-05:00</updated>
        <id>blog.superfeedr.com:/hijacking-api-requests-service-worker</id>
        <summary>The data consumed in a feed reader is updated often. Yet, for the best experience, we want to also serve the cached data.</summary>
        <content type="html">&lt;p&gt;&lt;a href=&quot;http://blog.superfeedr.com/service-workers/&quot;&gt;Last week&lt;/a&gt;, we’ve seen how to add a Service Worker to &lt;a href=&quot;https://river.news/&quot;&gt;our feed reader&lt;/a&gt; so that it loads faster by caching its &lt;em&gt;shell&lt;/em&gt;. One of the direct benefits of this is that our application shell is now also &lt;strong&gt;available offline&lt;/strong&gt;, even when the browser is not connected to the web.&lt;/p&gt;

&lt;p&gt;This week, we’ll see how we should also use the Service Worker API to cache the dynamic data coming from the &lt;a href=&quot;https://superfeedr.com/&quot;&gt;Superfeedr Feed API&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;service-worker-toolbox&quot;&gt;Service Worker Toolbox&lt;/h2&gt;

&lt;p&gt;Our shell is now cached immediately after the first visit to &lt;a href=&quot;https://river.news&quot;&gt;River.news&lt;/a&gt;. After this, the content of the shell (static HTML, CSS and javascript) are &lt;em&gt;always&lt;/em&gt; loaded only from the cache. (until of course we update the service worker).
The RSS feeds’ content will be updated more often, so we can’t use the same approach for the calls to Superfeedr’s API. Yet, we still want the best experience so we have to cache the content and show it to the user immediately. In a way, for each call to the API, we want to achieve 2 things at &lt;strong&gt;concurrently&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If there is any data in the cache, show that to the user&lt;/li&gt;
  &lt;li&gt;Make a request to Superfeedr’s API and fail silently if the application is offline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s a pretty common scenario in the &lt;a href=&quot;https://jakearchibald.com/2014/offline-cookbook/&quot;&gt;Offline Cookbook&lt;/a&gt; published by &lt;a href=&quot;https://twitter.com/jaffathecake&quot;&gt;Jake Archibald&lt;/a&gt;. As a consequence, Google implemented it in its &lt;a href=&quot;https://github.com/GoogleChrome/sw-toolbox&quot;&gt;sw-toolbox&lt;/a&gt; (&lt;code&gt;sw-toolbox&lt;/code&gt; is syntactic sugar on top of Service Workers, exactly like &lt;a href=&quot;https://github.com/GoogleChrome/sw-precache&quot;&gt;sw-precache&lt;/a&gt;. The scenario we described above is called &lt;code&gt;fastest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sw-toolbox&lt;/code&gt; provides a routing mechanism which hijacks all HTTP requests performed by the browser and applies any of the predefined recipes in the toolbox. Here’s the code we’re using for River.news:&lt;/p&gt;

&lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;toolbox.router.get(/^https:\/\/push.superfeedr.com\//, toolbox.fastest);
toolbox.router.get(/^https:\/\/www.google.com\/s2\/favicons/, toolbox.fastest);
toolbox.router.get(/^https:\/\/river.news\/up.html/, toolbox.networkOnly);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We see that for any request which matches the &lt;code&gt;/^https:\/\/push.superfeedr.com\//,&lt;/code&gt; regular expression, we apply the &lt;code&gt;toolbox.fastest&lt;/code&gt; recipe. We use the exact same approach for requests to &lt;code&gt;google.com/s2/favicons&lt;/code&gt; that we use to load the icons for each story.&lt;/p&gt;

&lt;p&gt;The last line is a bit different. We &lt;em&gt;only&lt;/em&gt; want to load this last resource using the network and never cache it.&lt;/p&gt;

&lt;h2 id=&quot;assessing-connectivity&quot;&gt;Assessing connectivity&lt;/h2&gt;

&lt;p&gt;Caching data is extremely useful when the application &lt;strong&gt;only has to display&lt;/strong&gt; information. However, if the local application needs to alter the data, caching can quickly turn into an engineering nightmare with race conditions, lost updates and more. Luckily for us, a feed reader is mostly about &lt;em&gt;consuming&lt;/em&gt; data and rarely about &lt;em&gt;altering&lt;/em&gt; it. The notable exception being that one might want to update their subscription list. To make things simpler, at this point, we want to disable any change to the subscription list while the application is offline.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;HTML5 has its own &lt;a href=&quot;http://w3c.github.io/netinfo/&quot;&gt;Network Information API&lt;/a&gt;. Not only is it &lt;a href=&quot;http://caniuse.com/#feat=netinfo&quot;&gt;barely implemented&lt;/a&gt;, it also fails to detect when the device on which our application is connected to a network, but not to the web.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In order to check if we can update our subscription list, the River.news application will just make a simple &lt;code&gt;HEAD&lt;/code&gt; request to &lt;a href=&quot;http://river.news/up.html&quot;&gt;&lt;code&gt;http://river.news/up.html&lt;/code&gt;&lt;/a&gt;. If the request fails, we assume that we’re offline and then disable the form fields. If it succeeds we can let the user add or remove feeds.&lt;/p&gt;

&lt;p&gt;The latest rule of our &lt;code&gt;sw-toolbox&lt;/code&gt; should now make sense: we cannot afford to cache the responses if we want to reliably detect when we are offline!&lt;/p&gt;

&lt;p&gt;There are &lt;em&gt;many&lt;/em&gt; other use cases to Service Workers. For example, in our feed reader, we could use Service Workers to white-list a set of 3rd party javascript script.&lt;/p&gt;

</content>
        <author>
            <name>Julien</name>
            <uri>http://ouvre-boite.com</uri>
        </author>
    </entry>
    
    <entry>
        <title>Adding Offline Support to a feed reader with Service Workers</title>
        
        <link href="http://blog.superfeedr.com/service-workers/"/>
        <published>2016-01-12T00:00:00-05:00</published>
        <updated>2016-01-12T00:00:00-05:00</updated>
        <id>blog.superfeedr.com:/service-workers</id>
        <summary>Feed readers are more useful when they work offline. Unfortunately, up until a couple months ago, the web’s technologies were not compatible with this requirement. Yet, the introduction of Service Workers is slowly changing this game and, at Superfeedr, we’re excited to see open web technologies catch up with capabilities of installable native apps.</summary>
        <content type="html">&lt;p&gt;Feed readers are more useful when they &lt;strong&gt;work offline&lt;/strong&gt;. Unfortunately, up until a couple months ago, the web’s technologies were not compatible with this requirement. Yet, the introduction of &lt;a href=&quot;http://www.w3.org/TR/service-workers/&quot;&gt;Service Workers&lt;/a&gt; is slowly changing this game and, at &lt;a href=&quot;https://superfeedr.com&quot;&gt;Superfeedr&lt;/a&gt;, we’re excited to see open web technologies catch up with capabilities of installable native apps.&lt;/p&gt;

&lt;p&gt;We have our very own RSS reader built on top of Superfeedr’s API: &lt;a href=&quot;https://superfeedr.com&quot;&gt;river.news&lt;/a&gt;. Let’s see what Service Workers can do for it and improve our code. As a reminder, this is a &lt;strong&gt;static single page application&lt;/strong&gt;: there’s no application server which computes a different response for each request. Check the &lt;a href=&quot;https://github.com/superfeedr/river.news&quot;&gt;source code&lt;/a&gt; on Github.&lt;/p&gt;

&lt;h2 id=&quot;service-workers&quot;&gt;Service Workers&lt;/h2&gt;

&lt;p&gt;Dozens of &lt;a href=&quot;https://changelog.com/must-watch-videos-service-workers/&quot;&gt;great&lt;/a&gt; &lt;a href=&quot;https://changelog.com/essential-reading-list-for-getting-started-with-service-workers/&quot;&gt;resources&lt;/a&gt; online provide excellent definitions and introductions to Service Workers. To us, it’s a &lt;em&gt;very significant upgrade to the web’s core philosophy&lt;/em&gt;. The web’s center is the &lt;a href=&quot;https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol&quot;&gt;HTTP protocol&lt;/a&gt; which stands for &lt;strong&gt;H&lt;/strong&gt;yper&lt;strong&gt;T&lt;/strong&gt;ext &lt;strong&gt;T&lt;/strong&gt;ransfer &lt;strong&gt;P&lt;/strong&gt;rotocol. Literally, this means our browsers are communicating with servers to receive &lt;strong&gt;hyper-text document&lt;/strong&gt;: the web pages. Later, these documents may load Javascript code which is finally executed. With ServiceWorkers, the &lt;strong&gt;order changes&lt;/strong&gt;: some javascript code can be executed &lt;em&gt;before&lt;/em&gt; anything else happens. These workers can then hijack HTTP request (and more) and provide alternative (or fallback) responses.&lt;/p&gt;

&lt;p&gt;Adding support to river.news would be very interesting on 2 levels:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Since the code is static, there’s &lt;em&gt;no need&lt;/em&gt; to load it from the file server after its first load. &lt;a href=&quot;https://subtome.com&quot;&gt;SubToMe&lt;/a&gt; used AppCache for this…. but AppCache &lt;a href=&quot;http://alistapart.com/article/application-cache-is-a-douchebag&quot;&gt;is so messy&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;When loading past stories from Superfeedr, we should keep them in the cache so that the user can read them even when they go offline or have a spotty connection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;an-application-shell&quot;&gt;An application shell&lt;/h2&gt;

&lt;p&gt;Most web applications have a &lt;strong&gt;base template&lt;/strong&gt; which is made of some HTML, CSS and Javascript used all across the application, even if there are multiple HTML pages. This &lt;strong&gt;application shell&lt;/strong&gt; should absolutely be cached by the browser so that it stays in memory. There should be no latency spent downloading it because it rarely changes.&lt;/p&gt;

&lt;p&gt;In the case of &lt;a href=&quot;https://river.news&quot;&gt;river.news&lt;/a&gt;, it’s actually fairly simple: there’s just a &lt;em&gt;single HTML page&lt;/em&gt;. There’s also a single javascript file for the application’s specific code. Since we use React and Jquery as dependencies, we consider them as part of the basic shell for our application. We also use Bootstrap’s CSS, so we’ll add it to the shell, as well as a bunch of icons.&lt;/p&gt;

&lt;p&gt;The application’s shell must immediately be cached the first time the page is loaded and we should only invalidate the cache for the files that have changed (incremental updates are much better than native apps!). Even though the Service Worker API is fairly simple, the Chrome team provides some syntactic sugar in the form of &lt;a href=&quot;https://github.com/GoogleChrome/sw-precache&quot;&gt;&lt;code&gt;sw-precache&lt;/code&gt;&lt;/a&gt;. This script lets anyone quickly define the files required for the shell and handles invalidation without &lt;strong&gt;any significant code change&lt;/strong&gt; to your own code!&lt;/p&gt;

&lt;p&gt;That was the easy part. Next week, we’ll see how we can also cache the API calls to Superfeedr for offline usage!&lt;/p&gt;

</content>
        <author>
            <name>Julien</name>
            <uri>http://ouvre-boite.com</uri>
        </author>
    </entry>
    
</feed>
