<?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>Forem: marcellothearcane</title>
    <description>The latest articles on Forem by marcellothearcane (@marcellothearcane).</description>
    <link>https://forem.com/marcellothearcane</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%2F105032%2F2b9643d7-118f-4c59-b7c1-0345c4cb4fca.jpeg</url>
      <title>Forem: marcellothearcane</title>
      <link>https://forem.com/marcellothearcane</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/marcellothearcane"/>
    <language>en</language>
    <item>
      <title>How I fixed this one weird bug!</title>
      <dc:creator>marcellothearcane</dc:creator>
      <pubDate>Mon, 22 Feb 2021 16:39:49 +0000</pubDate>
      <link>https://forem.com/marcellothearcane/how-i-fixed-this-one-weird-bug-2114</link>
      <guid>https://forem.com/marcellothearcane/how-i-fixed-this-one-weird-bug-2114</guid>
      <description>&lt;p&gt;I run a small web app for my company, which acts as a CRM + dashboard, using &lt;a href="https://nuxtjs.org/"&gt;Nuxt&lt;/a&gt; + &lt;a href="https://nhost.io/"&gt;Nhost&lt;/a&gt; and hosted on &lt;a href="https://vercel.com/"&gt;Vercel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This morning, I pushed a small update and sat back comfortable in the assurance of &lt;a href="https://vercel.com/docs/git/vercel-for-github#a-deployment-for-each-push"&gt;automatic continuous deployment&lt;/a&gt; taking care of everything.&lt;/p&gt;

&lt;p&gt;But I wouldn't be writing this if it had all gone smoothly, would I?&lt;/p&gt;

&lt;p&gt;The first time I noticed something was wrong, was when the dashboard redirected to the login page.  (It's set up to &lt;a href="https://dev.to/marcellothearcane/discussion-what-is-the-best-way-to-get-users-to-refresh-a-web-app-3gjf"&gt;auto-refresh on every update&lt;/a&gt;).  I went to log back in, but I noticed something odd:  &lt;strong&gt;Instead of being &lt;code&gt;my-site.my-domain.now.sh&lt;/code&gt;, the url was pointing to &lt;code&gt;my-site-my-domain.vercel.app&lt;/code&gt;.&lt;/strong&gt;  Why's that such a big deal?  Because I was using &lt;code&gt;.my-domain.now.sh&lt;/code&gt; as the &lt;a href="https://stackoverflow.com/questions/1062963/how-do-browser-cookie-domains-work"&gt;cookie domain&lt;/a&gt; for authentication!&lt;/p&gt;

&lt;p&gt;It turns out that buried in the Vercel changelog is &lt;a href="https://vercel.com/changelog/urls-are-becoming-consistent"&gt;this post&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As part of our strategy for making them simpler, we're starting with applying a consistent format on February 20th 2021:&lt;br&gt;
Custom Domains and Automatic URLs ending in now.sh will instead end in vercel.app.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic Deployment URLs like &lt;code&gt;project-d418mhwf5.vercel.app&lt;/code&gt; will gain the slug of the owner Vercel scope to match Automatic Branch URLs: &lt;code&gt;project-d418mhwf5-team.vercel.app&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatic Branch URLs like &lt;code&gt;project-git-update.team.vercel.app&lt;/code&gt; will lose their second subdomain level in favor of a dash: &lt;code&gt;project-git-update-team.vercel.app&lt;/code&gt;.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Automatic Project URLs like &lt;code&gt;project.team.vercel.app&lt;/code&gt; and Automatic Team Member URLs like &lt;code&gt;project-user.team.vercel.app&lt;/code&gt; will be adjusted like Automatic Branch URLs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Now&lt;/em&gt; they tell me!&lt;/p&gt;

&lt;p&gt;It should be as simple as changing the cookie-setting code to use &lt;code&gt;.vercel.app&lt;/code&gt; as the domain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;return this.cookies.set(`${this.options.prefix}.${name}`, value, {
&lt;/span&gt;  expires,
&lt;span class="gd"&gt;-  domain: !this.isDev ? '.my-domain.now.sh' : 'localhost',
&lt;/span&gt;&lt;span class="gi"&gt;+  domain: !this.isDev ? '.vercel.app' : 'localhost',
&lt;/span&gt;  path: '/',
  sameSite: false,
&lt;span class="err"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this didn't work.  What was going on?  I was doing something wrong, but I couldn't work it out because it had been working fine before with &lt;code&gt;.my-domain.now.sh&lt;/code&gt;.  I set a bunch of breakpoints around where cookies were being set, but they seemed to fail silently to no cookie being set.  I even tried setting cookies manually in the browser console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; document.cookie &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my=cookie;"&lt;/span&gt;
&lt;span class="s2"&gt;"my=cookie;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; document.cookie
&lt;span class="s2"&gt;"my=cookie"&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; document.cookie &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sub=my-site-my-domain.vercel.app; Domain=my-site-my-domain.vercel.app;"&lt;/span&gt;
&lt;span class="s2"&gt;"sub=my-site-my-domain.vercel.app; Domain=my-site-my-domain.vercel.app;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; document.cookie
&lt;span class="s2"&gt;"my=cookie; sub=my-site-my-domain.vercel.app"&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; document.cookie &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tld=.vercel.app; Domain=.vercel.app;"&lt;/span&gt;
&lt;span class="s2"&gt;"tld=.vercel.app; Domain=.vercel.app;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; document.cookie
&lt;span class="s2"&gt;"my=cookie; sub=my-site-my-domain.vercel.app"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Very strange - I couldn't set cookies at all, either through &lt;a href="https://www.npmjs.com/package/cookie-universal-nuxt"&gt;&lt;code&gt;cookie-universal-nuxt&lt;/code&gt;&lt;/a&gt; or through plain JS &lt;a href="https://developer.mozilla.org/en-US/docs/web/api/document/cookie"&gt;&lt;code&gt;document.cookie&lt;/code&gt;&lt;/a&gt;, if the cookie domain was &lt;code&gt;.vercel.app&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I had a niggling feeling that there was something stopping &lt;code&gt;.vercel.app&lt;/code&gt; being used, because then surely I'd be making a cookie that applied to all Vercel URLs.  Previously, &lt;code&gt;.my-domain.now.sh&lt;/code&gt; was another level of subdomains, so it might have had some sandboxing.  I knew you can't make cookies that apply to &lt;code&gt;.com&lt;/code&gt; or &lt;code&gt;.co.uk&lt;/code&gt;, so maybe I should refresh my understanding of that.  This train of thought led me to this very helpful &lt;a href="https://wiki.mozilla.org/Public_Suffix_List"&gt;Mozilla Wiki&lt;/a&gt; page.  I quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Previously, browsers used an algorithm which basically only denied setting wide-ranging cookies for top-level domains with no dots (e.g. com or org). However, this did not work for top-level domains where only third-level registrations are allowed (e.g. co.uk). In these cases, websites could set a cookie for co.uk which will be passed onto every website registered under co.uk.&lt;br&gt;
Clearly, this was a security risk as it allowed websites other than the one setting the cookie to read it, and therefore potentially extract sensitive information.&lt;br&gt;
Since there is no algorithmic method of finding the highest level at which a domain may be registered for a particular top-level domain (the policies differ with each registry), the only method is to create a list of all top-level domains and the level at which domains can be registered. This is the aim of the effective TLD list.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I wonder if this list has anything interesting in it?  &lt;a href="https://publicsuffix.org/list/public_suffix_list.dat#:~:text=vercel.app"&gt;Sure enough&lt;/a&gt;...&lt;/p&gt;

&lt;pre&gt;
  &lt;code&gt;
  // Vercel, Inc : https://vercel.com/
  // Submitted by Connor Davis 
  vercel.app
  vercel.dev
  now.sh
  &lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;Great!  That must be what's going on!  Now I had to commission a third-level subdomain &lt;code&gt;main.internal.mycompany.com&lt;/code&gt; using the &lt;code&gt;cname.vercel-dns.com&lt;/code&gt; provided.  This would then use auth on &lt;code&gt;internal.mycompany.com&lt;/code&gt; without polluting anything on the main domain.&lt;/p&gt;

&lt;p&gt;Sure enough, with the cookie URL reconfigured, the subdomains all set up, and a bit of luck, I could now log on without problems.  The last step was changing everyone's bookmarks, and updating the dashboard pages!&lt;/p&gt;

&lt;p&gt;☕&lt;/p&gt;

</description>
      <category>vercel</category>
      <category>cookies</category>
      <category>bugs</category>
    </item>
    <item>
      <title>Get code coverage reports with Github Actions and Codecov</title>
      <dc:creator>marcellothearcane</dc:creator>
      <pubDate>Thu, 08 Oct 2020 09:23:35 +0000</pubDate>
      <link>https://forem.com/marcellothearcane/get-code-coverage-reports-with-github-actions-and-codecov-1n74</link>
      <guid>https://forem.com/marcellothearcane/get-code-coverage-reports-with-github-actions-and-codecov-1n74</guid>
      <description>&lt;p&gt;TLDR: &lt;strong&gt;&lt;em&gt;Show me the money&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;So, you've spent some time getting tests set up on your project.  How do you show the world?&lt;/p&gt;

&lt;p&gt;A popular service is &lt;a href="https://codecov.io" rel="noopener noreferrer"&gt;Codecov&lt;/a&gt;, and you'll probably recognise their badges from Github repositories:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe8jbt864adnofe6uk8np.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe8jbt864adnofe6uk8np.png" alt="100% coverage on Codecov"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  However
&lt;/h3&gt;

&lt;p&gt;Codecov is a &lt;em&gt;static&lt;/em&gt; analysis tool, which means you have to upload reports that have already been tested.  One option is to commit your &lt;code&gt;coverage&lt;/code&gt; folder, but this is a bad idea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have to run your tests before &lt;em&gt;every&lt;/em&gt; commit.  Chances are you'll forget, and your coverage will be out of date.&lt;/li&gt;
&lt;li&gt;You won't be able to edit away from your main computer (i.e. you can't update the tests from your phone).&lt;/li&gt;
&lt;li&gt;It isn't automated enough, and everyone knows more automation is better.&lt;/li&gt;
&lt;li&gt;Probably loads of bad things.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Github Actions to the rescue!
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;Github Actions&lt;/a&gt; is a fairly new (I think?) feature that allows you to add &lt;a href="https://en.wikipedia.org/wiki/Continuous_integration" rel="noopener noreferrer"&gt;CI&lt;/a&gt; to your project.&lt;/p&gt;

&lt;p&gt;There's a few &lt;a href="https://github.com/actions/starter-workflows" rel="noopener noreferrer"&gt;default templates&lt;/a&gt;, but unfortunately none that I could find for running tests and sending the reports over to Codecov.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up a Github Action
&lt;/h2&gt;

&lt;p&gt;Github actions are stored in &lt;code&gt;.github/workflows&lt;/code&gt;, and are &lt;code&gt;YAML&lt;/code&gt; files that specify how the job should run.  &lt;a href="https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions" rel="noopener noreferrer"&gt;Check out the docs to find out more&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We'll set up a simple task by adding a file called &lt;code&gt;codecov-test-suites.yml&lt;/code&gt; and adding the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/codecov-test-suites.yml&lt;/span&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Test Suites&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sets up a new workflow that triggers for every push.&lt;/p&gt;

&lt;p&gt;Now we need to make it do things!  You need to add a job to this file, which does the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetches the files&lt;/li&gt;
&lt;li&gt;Installs the dependencies&lt;/li&gt;
&lt;li&gt;Runs the test&lt;/li&gt;
&lt;li&gt;Uploads the test to Codecov&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is easy.  Add this to the &lt;code&gt;codecov-test-suites.yml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt; &lt;span class="c1"&gt;# Check out your repository&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn&lt;/span&gt; &lt;span class="c1"&gt;# Install dependencies&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn test --coverage&lt;/span&gt; &lt;span class="c1"&gt;# Run test&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash &amp;lt;(curl -s https://codecov.io/bash)&lt;/span&gt; &lt;span class="c1"&gt;# Upload to Codecov&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your test should run, but apparently you have 0% coverage.  What?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fihp2itmubuil4q942rl5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fihp2itmubuil4q942rl5.png" alt="Codecov can't process your report"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It turns out the tests are run in a weird folder, and this doesn't tie up with your repository structure, so Codecov gets confused.&lt;/p&gt;

&lt;p&gt;To fix this, you need to add a &lt;code&gt;codecov.yml&lt;/code&gt; file to your project root.  In here, we'll specify how to fix the file paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# codecov.yml&lt;/span&gt;

&lt;span class="na"&gt;fixes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/home/runner/work/&amp;lt;project&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name&amp;gt;/&amp;lt;project&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name&amp;gt;/::"&lt;/span&gt; &lt;span class="c1"&gt;# Correct paths&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit &lt;code&gt;&amp;lt;project name&amp;gt;&lt;/code&gt; to your repository name from Github, and commit this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Huzzah!&lt;/strong&gt; Github Actions should now be automagically running tests every time you push and sending to Codecov!&lt;/p&gt;

&lt;p&gt;Be sure to head to Codecov's badge settings and get that sweet SVG goodness:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F95llf3p3b462lavs73yc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F95llf3p3b462lavs73yc.png" alt="Badges badges badges badges badges!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember that 100% badge from earlier?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe8jbt864adnofe6uk8np.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe8jbt864adnofe6uk8np.png" alt="Can't get enough of that 100%"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  The money
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// package.json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Make sure jest creates lcov reports&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;collectCoverage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;coverageReporters&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lcov&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/codecov-test-suites.yml&lt;/span&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Test Suites&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt; &lt;span class="c1"&gt;# Check out your repository&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn&lt;/span&gt; &lt;span class="c1"&gt;# Install dependencies&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn test --coverage&lt;/span&gt; &lt;span class="c1"&gt;# Run test&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash &amp;lt;(curl -s https://codecov.io/bash)&lt;/span&gt; &lt;span class="c1"&gt;# Upload to Codecov&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# codecov.yml&lt;/span&gt;

&lt;span class="na"&gt;fixes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/home/runner/work/&amp;lt;project&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name&amp;gt;/&amp;lt;project&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name&amp;gt;/::"&lt;/span&gt; &lt;span class="c1"&gt;# Correct paths&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>coverage</category>
      <category>jest</category>
      <category>github</category>
      <category>testing</category>
    </item>
    <item>
      <title>How to CSP your Netlify projects</title>
      <dc:creator>marcellothearcane</dc:creator>
      <pubDate>Wed, 23 Sep 2020 09:48:37 +0000</pubDate>
      <link>https://forem.com/marcellothearcane/how-to-csp-your-netlify-projects-4ff1</link>
      <guid>https://forem.com/marcellothearcane/how-to-csp-your-netlify-projects-4ff1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TLDR: I made &lt;a href="https://www.npmjs.com/package/netlify-plugin-csp-generator" rel="noopener noreferrer"&gt;this Netlify plugin for CSP&lt;/a&gt;.  You should give it a try.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Have you ever seen the full fury of dev tools spitting blood/&lt;code&gt;blocked:csp&lt;/code&gt; at you?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fakofkqumkf4ctj9233hm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fakofkqumkf4ctj9233hm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No? Well you should have.  Because that means you have at least tried to set up a &lt;code&gt;Content-Security-Policy&lt;/code&gt; on your website before.&lt;/p&gt;

&lt;p&gt;Setting up a content security policy is essential for preventing XSS attacks - which is a big deal, because &lt;a href="https://www.precisesecurity.com/articles/cross-site-scripting-xss-makes-nearly-40-of-all-cyber-attacks-in-2019/" rel="noopener noreferrer"&gt;XSS was responsible for 40% cyber attacks in 2019&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, it's not always fun to set up.  If you're using something like &lt;a href="https://gridsome.org/" rel="noopener noreferrer"&gt;Gridsome&lt;/a&gt; on &lt;a href="http://netlify.com/" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt;, you will come across two key issues that you can't solve just by adding a &lt;code&gt;Content-Security-Policy&lt;/code&gt; key to the headers in your &lt;code&gt;netlify.toml&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Gridsome (and Gatsby) inline the initial state, which is a big &lt;code&gt;&amp;lt;script&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; block.&lt;/li&gt;
&lt;li&gt;Vue uses inline styles for &lt;code&gt;v-show&lt;/code&gt;, like &lt;code&gt;style="display:none;"&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both of these things are blocked by CSP rules, which is good because you don't want random scripts being added into your website or your styles being messed up (someone styling another link as a 'pay now' button for example).&lt;/p&gt;

&lt;p&gt;To fix this, you need to generate a cryptographic hash of the inline script, so the browser knows this is okay and hasn't been tampered with.  If you search online, you might find some &lt;a href="https://stackoverflow.com/q/17766817/5868894" rel="noopener noreferrer"&gt;bad advice&lt;/a&gt;, like using &lt;code&gt;unsafe-inline&lt;/code&gt;. (&lt;a href="https://www.biblegateway.com/passage/?search=Proverbs+20%3A14&amp;amp;version=DARBY" rel="noopener noreferrer"&gt;Bad! Bad! saith the buyer&lt;/a&gt;...)&lt;/p&gt;

&lt;p&gt;If you're using Netlify, you can use &lt;a href="https://www.npmjs.com/package/netlify-plugin-csp-generator" rel="noopener noreferrer"&gt;this amazing package I made earlier&lt;/a&gt; to generate &lt;code&gt;sha256&lt;/code&gt; hashes of inline scripts and styles for your &lt;code&gt;Content-Security-Policy&lt;/code&gt; headers.  Head over to the Github repo, and try it out on your Netlify project.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/MarcelloTheArcane" rel="noopener noreferrer"&gt;
        MarcelloTheArcane
      &lt;/a&gt; / &lt;a href="https://github.com/MarcelloTheArcane/netlify-plugin-csp-generator" rel="noopener noreferrer"&gt;
        netlify-plugin-csp-generator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Generate CSP headers from inline script hashes
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;netlify-plugin-csp-generator&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/netlify-plugin-csp-generator" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/eb803d248350c803547c6c84d852a50037efa9a178f568dd70beb9bbd306ba26/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f6e65746c6966792d706c7567696e2d6373702d67656e657261746f722e737667" alt="NPM"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/MarcelloTheArcane/netlify-plugin-csp-generator" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/408c22a1e68fe257cd4669324fde226619b355d6a9c3f54510ef8c7809a03dfe/68747470733a2f2f636f6465636f762e696f2f67682f4d617263656c6c6f546865417263616e652f6e65746c6966792d706c7567696e2d6373702d67656e657261746f722f6272616e63682f6d61737465722f67726170682f62616467652e737667" alt="codecov"&gt;&lt;/a&gt;
&lt;a href="https://github.com/MarcelloTheArcane/netlify-plugin-csp-generator/actions?query=workflow%3ACodeQL" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/MarcelloTheArcane/netlify-plugin-csp-generator/workflows/CodeQL/badge.svg" alt="CodeQL"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Generate &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;Content-Security-Policy&lt;/code&gt;&lt;/a&gt; headers from inline script and style hashes&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When running things like &lt;a href="https://www.gatsbyjs.com/" rel="nofollow noopener noreferrer"&gt;Gatsby&lt;/a&gt; or &lt;a href="https://gridsome.org/" rel="nofollow noopener noreferrer"&gt;Gridsome&lt;/a&gt;, the initial state is stored inside a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag
Modern browser content security policies don't like inline scripts or styles, so to get around it you need to add either a &lt;a href="https://en.wikipedia.org/wiki/Cryptographic_nonce" rel="nofollow noopener noreferrer"&gt;cryptographic nonce&lt;/a&gt; or a &lt;a href="https://en.wikipedia.org/wiki/Cryptographic_hash_function" rel="nofollow noopener noreferrer"&gt;cryptographic hash&lt;/a&gt; of each script
A nonce is out of the question, because you can't update it for each load.&lt;/p&gt;
&lt;p&gt;This package generates a crypographic hash (&lt;a href="https://en.wikipedia.org/wiki/SHA-2" rel="nofollow noopener noreferrer"&gt;SHA-256&lt;/a&gt;) of all inline scripts and styles in each HTML file, and adds it to the &lt;code&gt;_headers&lt;/code&gt; file along with other policies of your choice.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
Netlify lets you add a &lt;code&gt;Content-Security-Policy&lt;/code&gt; header in your &lt;a href="https://docs.netlify.com/routing/headers/#syntax-for-the-netlify-configuration-file" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;netlify.toml&lt;/code&gt;&lt;/a&gt;.  This will overwrite values inside &lt;code&gt;_headers&lt;/code&gt;, so don't do that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you have an existing &lt;code&gt;_headers&lt;/code&gt; file, this will append to the existing file.  Just make sure the file ends on…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/MarcelloTheArcane/netlify-plugin-csp-generator" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;If you're not using Netlify, you're on your own.  Sorry about that.&lt;/p&gt;




&lt;p&gt;Want to check your website for XSS vulnerabilities? Just run this in your browser console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;script&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alert("hacked!")&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flq6f4myt9qjr1qqh9lzz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flq6f4myt9qjr1qqh9lzz.png" alt="This website is safe from XSS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzysainiyk1a5h2dirka1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzysainiyk1a5h2dirka1.png" alt="This website is not safe from XSS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;😱&lt;/p&gt;

</description>
      <category>node</category>
      <category>npm</category>
      <category>netlify</category>
      <category>showdev</category>
    </item>
    <item>
      <title>QlockTwo in your browser!</title>
      <dc:creator>marcellothearcane</dc:creator>
      <pubDate>Thu, 06 Feb 2020 16:33:01 +0000</pubDate>
      <link>https://forem.com/marcellothearcane/qlocktwo-in-your-browser-3e5j</link>
      <guid>https://forem.com/marcellothearcane/qlocktwo-in-your-browser-3e5j</guid>
      <description>&lt;p&gt;Have you seen the &lt;a href="https://qlocktwo.com/en/qlocktwo-classic/"&gt;QlockTwo&lt;/a&gt;? It's pretty cool. Here's a version with HTML and Javascript.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/tillysinteriors/embed/GRJKjNd?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>codepen</category>
      <category>vanilla</category>
    </item>
    <item>
      <title>I made a Nuxt template for Nhost! </title>
      <dc:creator>marcellothearcane</dc:creator>
      <pubDate>Thu, 16 Jan 2020 07:22:09 +0000</pubDate>
      <link>https://forem.com/marcellothearcane/i-made-a-nuxt-template-for-nhost-1mj9</link>
      <guid>https://forem.com/marcellothearcane/i-made-a-nuxt-template-for-nhost-1mj9</guid>
      <description>&lt;p&gt;If you haven't heard, &lt;a href="https://nhost.io/" rel="noopener noreferrer"&gt;Nhost&lt;/a&gt; is a really cool preconfigured Hasura instance, with authentication / file storage built in!&lt;/p&gt;

&lt;p&gt;Think Firebase on GraphQL, with the plus of all being open source.&lt;/p&gt;

&lt;p&gt;So if you're looking for the next backend for your &lt;a href="https://nuxtjs.org/" rel="noopener noreferrer"&gt;Nuxt&lt;/a&gt; project, give Nhost a try!&lt;/p&gt;

&lt;p&gt;You can use my template to get started:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/MarcelloTheArcane" rel="noopener noreferrer"&gt;
        MarcelloTheArcane
      &lt;/a&gt; / &lt;a href="https://github.com/MarcelloTheArcane/nhost-template" rel="noopener noreferrer"&gt;
        nhost-template
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;NHost Template for Nuxt&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;For detailed explanation on how things work, check out &lt;a href="https://nuxtjs.org" rel="nofollow noopener noreferrer"&gt;Nuxt.js docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://nhost.io/" rel="nofollow noopener noreferrer"&gt;NHost is cool&lt;/a&gt;. It's a PostgreSQL database with GraphQL, file storage, and authentication built in. You should check it out.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Preconfiguration&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;GraphQL support from &lt;a href="https://github.com/nuxt-community/apollo-module" rel="noopener noreferrer"&gt;&lt;code&gt;@nuxtjs/apollo&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Authentication support from &lt;a href="https://github.com/nuxt-community/auth-module" rel="noopener noreferrer"&gt;&lt;code&gt;@nuxtjs/auth&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Apollo configuration&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;There is a configuration for apollo in &lt;code&gt;plugins/apollo.js&lt;/code&gt; which adds the bearer token to websocket requests (for subscriptions).&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Auth configuration&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;The authentication has a custom configuration provided by &lt;code&gt;plugins/refreshScheme.js&lt;/code&gt;. This adds support for the JWT refresh scheme used by NHost.&lt;/p&gt;
&lt;p&gt;There is also an auth configuration in &lt;code&gt;plugins/auth.js&lt;/code&gt; which handles whether a user should be able to access a page.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Style configuration&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;This project is preconfigured with &lt;a href="https://tailwindcss.com/" rel="nofollow noopener noreferrer"&gt;Tailwind&lt;/a&gt;. It's pretty awesome, but if you want to use something else, remove the tailwind dependencies and add something new.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Template setup&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;From Github, you can click on &lt;a href="https://github.com/MarcelloTheArcane/nhost-template/generate" rel="noopener noreferrer"&gt;&lt;code&gt;Use this template&lt;/code&gt;&lt;/a&gt; to create…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/MarcelloTheArcane/nhost-template" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>templates</category>
      <category>hasura</category>
      <category>nuxt</category>
      <category>graphql</category>
    </item>
    <item>
      <title>I've written my first blog post!</title>
      <dc:creator>marcellothearcane</dc:creator>
      <pubDate>Sat, 23 Nov 2019 16:56:58 +0000</pubDate>
      <link>https://forem.com/marcellothearcane/i-ve-written-my-first-blog-post-2o5l</link>
      <guid>https://forem.com/marcellothearcane/i-ve-written-my-first-blog-post-2o5l</guid>
      <description>&lt;p&gt;Nearly two weeks ago (how time flies) &lt;a href="https://dev.to/marcellothearcane/what-should-i-write-blog-posts-about-1h7a"&gt;I asked for suggestions&lt;/a&gt; on what to write blog posts about for &lt;a href="https://nhost.io"&gt;Nhost&lt;/a&gt; a GraphQL-based backend as a service.&lt;/p&gt;

&lt;p&gt;Here's the first one! I'm new to all this, so your feedback is appreciated - as well as any suggestions for more blogs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.nhost.io/building-a-photo-app-with-nhost/"&gt;https://blog.nhost.io/building-a-photo-app-with-nhost/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blogging</category>
      <category>writing</category>
      <category>articles</category>
    </item>
    <item>
      <title>What should I write blog posts about?</title>
      <dc:creator>marcellothearcane</dc:creator>
      <pubDate>Sun, 10 Nov 2019 15:15:14 +0000</pubDate>
      <link>https://forem.com/marcellothearcane/what-should-i-write-blog-posts-about-1h7a</link>
      <guid>https://forem.com/marcellothearcane/what-should-i-write-blog-posts-about-1h7a</guid>
      <description>&lt;p&gt;I've been given a writer account for the blogging platform of the startup &lt;a href="https://nhost.io"&gt;Nhost&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Nhost is a hosted, GraphQL-based, Hasura-backed altermative to databases-as-a-service, like Google Firebase. &lt;/p&gt;

&lt;p&gt;It's really new, and really awesome, and I think it would be cool to make some examples demonstrating what you can do with it, but I need project ideas!&lt;/p&gt;

&lt;p&gt;Everything seems to have a 'todo app' example, but that doesn't always help people in the real world.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are some simple projects I could make that would be useful to you, if you were going to get started with Nhost?&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>blogs</category>
      <category>helpwanted</category>
    </item>
    <item>
      <title>Discussion: What is the best way to get users to refresh a web app?</title>
      <dc:creator>marcellothearcane</dc:creator>
      <pubDate>Tue, 10 Sep 2019 20:35:09 +0000</pubDate>
      <link>https://forem.com/marcellothearcane/discussion-what-is-the-best-way-to-get-users-to-refresh-a-web-app-3gjf</link>
      <guid>https://forem.com/marcellothearcane/discussion-what-is-the-best-way-to-get-users-to-refresh-a-web-app-3gjf</guid>
      <description>&lt;p&gt;I'm currently developing a Nuxt web app for our staff to use for processing orders. &lt;/p&gt;

&lt;p&gt;At the moment, there are a lot of bugs being fixed or new features implemented.&lt;/p&gt;

&lt;p&gt;The trouble is, the users generally keep the tab open for days on end, since they are using it constantly - and since it's Nuxt, they don't ever hard-refresh.&lt;/p&gt;

&lt;p&gt;This means they don't get the bug fixes they asked for as soon as they have been deployed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the simplest notification system for me to quickly post a 'Refresh this page to see the latest version' popup?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm using Nuxt, GraphQL, and Zeit deployment, so if it could trigger from a successful deploy on Zeit that would be awesome.&lt;/p&gt;

</description>
      <category>nuxt</category>
      <category>zeit</category>
      <category>graphql</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
