<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: jayebird 🐙🏳️‍🌈</title>
    <description>The latest articles on DEV Community by jayebird 🐙🏳️‍🌈 (@dinosaurenby).</description>
    <link>https://dev.to/dinosaurenby</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F539853%2Fb645906d-adc8-4143-a5c0-0c757bab7b2f.jpg</url>
      <title>DEV Community: jayebird 🐙🏳️‍🌈</title>
      <link>https://dev.to/dinosaurenby</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dinosaurenby"/>
    <language>en</language>
    <item>
      <title>How do you test a design system?</title>
      <dc:creator>jayebird 🐙🏳️‍🌈</dc:creator>
      <pubDate>Thu, 25 Feb 2021 17:52:17 +0000</pubDate>
      <link>https://dev.to/dinosaurenby/how-do-you-test-a-design-system-1ije</link>
      <guid>https://dev.to/dinosaurenby/how-do-you-test-a-design-system-1ije</guid>
      <description>&lt;p&gt;I've inherited a component library that I'm bringing back to life.&lt;/p&gt;

&lt;p&gt;In the past I've worked on React component libraries and used tools like &lt;a href="https://storybook.js.org/"&gt;Storybook&lt;/a&gt; to develop them. Testing these is pretty easy - I tend to use mostly &lt;a href="https://testing-library.com/docs/react-testing-library/intro/"&gt;react-testing-library&lt;/a&gt; and &lt;a href="https://jestjs.io/"&gt;jest&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But this particular library is different—each component is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;scss&lt;/strong&gt; file for styling&lt;/li&gt;
&lt;li&gt;optionally, some &lt;strong&gt;javascript&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;markdown&lt;/strong&gt; file that combines written guidance for using the component with code samples and live previews&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not that different from the &lt;a href="https://design-system.service.gov.uk/"&gt;GOV.UK design system&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Testing the javascript parts is easy enough, but it's only a small part of the overall library.&lt;/p&gt;

&lt;p&gt;How do you go about testing something like this in a robust way?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>css</category>
      <category>javascript</category>
      <category>healthydebate</category>
    </item>
    <item>
      <title>The server is back, baby</title>
      <dc:creator>jayebird 🐙🏳️‍🌈</dc:creator>
      <pubDate>Wed, 30 Dec 2020 16:56:12 +0000</pubDate>
      <link>https://dev.to/dinosaurenby/the-server-is-back-baby-5e72</link>
      <guid>https://dev.to/dinosaurenby/the-server-is-back-baby-5e72</guid>
      <description>&lt;p&gt;2021 could well be the year of the server's glorious return.&lt;/p&gt;

&lt;p&gt;The React team at Facebook have previewed &lt;a href="https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html" rel="noopener noreferrer"&gt;server components&lt;/a&gt;, and the people at Basecamp have released &lt;a href="https://hotwire.dev/" rel="noopener noreferrer"&gt;Hotwire&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1341072021099327489-294" src="https://platform.twitter.com/embed/Tweet.html?id=1341072021099327489"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1341072021099327489-294');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1341072021099327489&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1341420143239450624-929" src="https://platform.twitter.com/embed/Tweet.html?id=1341420143239450624"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1341420143239450624-929');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1341420143239450624&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;The approaches are very different, but both tools seem to be about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;writing less JavaScript&lt;/li&gt;
&lt;li&gt;doing more on the server&lt;/li&gt;
&lt;li&gt;dealing in plain old HMTL whenever we can&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why does it matter?
&lt;/h2&gt;

&lt;p&gt;The past few years of web development have been about &lt;a href="https://jamstack.org/" rel="noopener noreferrer"&gt;shifting as much as possible &lt;em&gt;off&lt;/em&gt; the server&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Companies like Netlify have been arguing hard for making our apps as &lt;em&gt;static&lt;/em&gt; as possible, and building our dynamic features with client JavaScript,APIs and serverless functions.&lt;/p&gt;

&lt;p&gt;This is arguably a faster, more secure way of doing things, but it does have downsides.&lt;/p&gt;

&lt;p&gt;Doing everything statically can add complexity, and shifting the burden of work from our servers to the user's browser makes it harder to progresssively enhance our apps: we're beholden to the speed of the user's connection and hardware.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1344376354955935744-818" src="https://platform.twitter.com/embed/Tweet.html?id=1344376354955935744"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1344376354955935744-818');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1344376354955935744&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Client-rendered single page apps &lt;em&gt;still&lt;/em&gt; have &lt;a href="https://www.gatsbyjs.com/blog/2020-02-10-accessible-client-side-routing-improvements/" rel="noopener noreferrer"&gt;accessibility issues that are hard to solve&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After a few years of this, it looks like the pendulum is now swinging back in the other direction.&lt;/p&gt;

&lt;p&gt;Maybe the server is good for some things after all!&lt;/p&gt;

&lt;h2&gt;
  
  
  How do they work?
&lt;/h2&gt;

&lt;p&gt;React's server components are a carefully-considered redo of what Next.js does now with &lt;code&gt;getServerSideProps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With Next.js today, you can only do server-side operations on top level "page" components. This would remove that limitation.&lt;/p&gt;

&lt;p&gt;Meanwhile, Basecamp's Hotwire is an evolution of the &lt;a href="https://github.com/turbolinks/turbolinks" rel="noopener noreferrer"&gt;Turbolinks&lt;/a&gt; library that comes standard with all new Rails apps.&lt;/p&gt;

&lt;p&gt;It seems intended to be a Rails companion, though I expect there's a way to use it seperately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should I learn it now?
&lt;/h2&gt;

&lt;p&gt;Probably not quite yet!&lt;/p&gt;

&lt;p&gt;React's server components are a way off yet—all we can do is experiment with the demo.&lt;/p&gt;

&lt;p&gt;While Hotwire is apparently production-ready, it'll take a little while for examples, documentation and patterns to get good enough for me to consider using it, at least.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the reaction been?
&lt;/h2&gt;

&lt;p&gt;Everyone seems to love Facebook's server components, though there's a lot of unanswered questions.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1343086245665067010-798" src="https://platform.twitter.com/embed/Tweet.html?id=1343086245665067010"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1343086245665067010-798');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1343086245665067010&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;People seem more confused about Hotwire. Maybe it's a sense of humour thing?&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1341479796287676416-37" src="https://platform.twitter.com/embed/Tweet.html?id=1341479796287676416"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1341479796287676416-37');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1341479796287676416&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Either way, I'm keen to see where this goes.&lt;/p&gt;

&lt;p&gt;Exciting times ahead!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>rails</category>
      <category>react</category>
      <category>healthydebate</category>
    </item>
    <item>
      <title>Using JWTs for authentication—is it worth the effort?</title>
      <dc:creator>jayebird 🐙🏳️‍🌈</dc:creator>
      <pubDate>Mon, 14 Dec 2020 23:12:21 +0000</pubDate>
      <link>https://dev.to/dinosaurenby/using-jwts-for-authentication-is-it-worth-the-effort-nhi</link>
      <guid>https://dev.to/dinosaurenby/using-jwts-for-authentication-is-it-worth-the-effort-nhi</guid>
      <description>&lt;p&gt;When you look for advice on how to authenticate users of an Express/Node.js API, the most popular answer seems to be "use JSON web tokens".&lt;/p&gt;

&lt;p&gt;I took this advice as read when I was building my first few APIs. I dilligently built the middleware for signing, verifying and revoking tokens, plus the client-side code for keeping them.&lt;/p&gt;

&lt;p&gt;A few years later I discovered Rails. I was very late to the party, but the simplicity of using Rails &lt;a href="https://www.tutorialspoint.com/ruby-on-rails/rails-session-cookies.htm"&gt;session cookies&lt;/a&gt; was really attractive after the hassle of building secure authentication again and again.&lt;/p&gt;

&lt;p&gt;So, I've recently started building another Node/Express API, and I've decided to use the same session approach. It's been much less stressful.&lt;/p&gt;

&lt;p&gt;The setup for &lt;a href="https://www.npmjs.com/package/express-session"&gt;&lt;code&gt;express-session&lt;/code&gt;&lt;/a&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server.use(session({
    store: new (require("connect-pg-simple")(session))({
    }),
    secret: process.env.SESSION_SECRET,
    cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 }
}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then in my route handlers, it's as simple as saying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// where 'user' is the user who has just authenticated
req.session.userId = user.id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because sessions are stored on the server and the client only gets an encrypted cookie, this seems foolproof and easy to maintain.&lt;/p&gt;

&lt;p&gt;The cookie is passed in automatically with every request - it &lt;em&gt;just works&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, I'm wondering why people bother with the extra overhead of JWTs at all?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The reasons I normally hear are:&lt;/p&gt;

&lt;h2&gt;
  
  
  'JWTs are more scalable when your app needs to grow'
&lt;/h2&gt;

&lt;p&gt;I guess this might be true if you're keeping sessions in the memory of a particular app instance, but any realistic implementation involves an &lt;em&gt;external&lt;/em&gt; session store.&lt;/p&gt;

&lt;p&gt;Even my minimal example above uses a table on the PostgreSQL database that powers the rest of my app.&lt;/p&gt;

&lt;p&gt;That database is an &lt;a href="https://www.heroku.com/postgres"&gt;external service&lt;/a&gt;—it's horizontally scalable out of the box. This doesn't seem to be a realistic problem?&lt;/p&gt;

&lt;h2&gt;
  
  
  'JWTs are more secure'
&lt;/h2&gt;

&lt;p&gt;Recently I've seen lots of people suggesting it's easier for JWTs to be stolen by XSS attacks, especially if you keep them in localStorage.&lt;/p&gt;

&lt;p&gt;The current wisdom seems to be that you need to store them as a &lt;code&gt;httpOnly&lt;/code&gt; cookie. So...why not just use cookies to start with?&lt;/p&gt;

&lt;h2&gt;
  
  
  'JWTs are stateless'
&lt;/h2&gt;

&lt;p&gt;This one I do understand - a stateless API is ideal, easier to test.&lt;/p&gt;

&lt;p&gt;But what's the harm in a session that stores just the user's ID, say? Is that tiny bit of state really that bad?&lt;/p&gt;

&lt;p&gt;To take it a bit further for the sake of argument, let's say we used the &lt;a href="https://github.com/expressjs/cookie-session"&gt;cookie-session&lt;/a&gt; store.&lt;/p&gt;

&lt;p&gt;What's the difference between this and using a JWT in a cookie? Just the way the token is formatted/encrypted?&lt;/p&gt;

&lt;h2&gt;
  
  
  'JWTs still work when the API is on a different domain'
&lt;/h2&gt;

&lt;p&gt;This one makes sense too - cookies should be restricted to a particular domain, and if we're making requests to a third-party API on a different domain, we'll need to manually handle a token.&lt;/p&gt;

&lt;p&gt;But how do we square this with the best practice to store JWTs in cookies rather than localStorage from earlier?&lt;/p&gt;

&lt;h2&gt;
  
  
  Am I wrong?
&lt;/h2&gt;

&lt;p&gt;What am I missing?&lt;/p&gt;

&lt;p&gt;What situations would a JWT be worth the effort in?&lt;/p&gt;

&lt;p&gt;Do you have a preference for sessions over JWT, or the reverse?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>node</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>I've published my first WordPress plugin!</title>
      <dc:creator>jayebird 🐙🏳️‍🌈</dc:creator>
      <pubDate>Mon, 14 Dec 2020 00:21:42 +0000</pubDate>
      <link>https://dev.to/dinosaurenby/i-ve-published-my-first-wordpress-plugin-3kp9</link>
      <guid>https://dev.to/dinosaurenby/i-ve-published-my-first-wordpress-plugin-3kp9</guid>
      <description>&lt;p&gt;Showing users things near them is a really common user need for all sorts of apps and websites.&lt;/p&gt;

&lt;p&gt;It could be used to power anything from "branch finder" features on retail sites to nearby drivers on a ride-hailing app. &lt;/p&gt;

&lt;p&gt;For my day job, I need to build this kind of functionality roughly once every few months, so I was keen to find a way to package it up into something reusable.&lt;/p&gt;

&lt;p&gt;I've implemented it in Node.js and Rails before, but I was curious about a WordPress implementation - which is what &lt;em&gt;this&lt;/em&gt; is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cjd3Y0z2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ryfopq1g4xhk2wwc5nmx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cjd3Y0z2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ryfopq1g4xhk2wwc5nmx.jpg" alt="Example screens from a location-aware app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;After making over half a dozen apps &lt;a href="https://github.com/jhackett1/age-uk-boost"&gt;like this&lt;/a&gt;, you start to wonder if there's a better way!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;It's a three step process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You provide a &lt;strong&gt;geocoded&lt;/strong&gt; dataset to search. They could be shops, offices, childminders, zoos—anything, really. You make sure that they have latitude and longitude metadata.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The user provides their location with a text input, which we also geocode. We use &lt;a href="https://nominatim.openstreetmap.org/ui/search.html"&gt;Nominatim's excellent free API&lt;/a&gt; to do this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, we use the &lt;a href="https://en.wikipedia.org/wiki/Haversine_formula"&gt;haversine formula&lt;/a&gt; in SQL to calculate the distance to each point in the dataset. It takes into account the curvature of the earth, so we get super-accurate results even on international scales!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The plugin
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://wordpress.org/plugins/wp-geo-search"&gt;Take a look and tell me what you think!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's my first WP plugin that I've actually gone to the extra effort of publishing, so I'm keen to keep adding features.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>php</category>
      <category>sql</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
