<?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: Brenden Niedermeyer (he/him)</title>
    <description>The latest articles on DEV Community by Brenden Niedermeyer (he/him) (@nieds).</description>
    <link>https://dev.to/nieds</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%2F22805%2Fea9a095b-dece-411c-88e2-68f00b832878.jpeg</url>
      <title>DEV Community: Brenden Niedermeyer (he/him)</title>
      <link>https://dev.to/nieds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nieds"/>
    <language>en</language>
    <item>
      <title>Rebuilding My Home on the Web - Update #3: Ship It!</title>
      <dc:creator>Brenden Niedermeyer (he/him)</dc:creator>
      <pubDate>Fri, 23 Dec 2022 10:00:00 +0000</pubDate>
      <link>https://dev.to/nieds/rebuilding-my-home-on-the-web-update-3-ship-it-4d9m</link>
      <guid>https://dev.to/nieds/rebuilding-my-home-on-the-web-update-3-ship-it-4d9m</guid>
      <description>&lt;p&gt;This post is part of a series. You can view the other posts here: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://brenden.codes/rebuilding-my-home-on-the-web" rel="noopener noreferrer"&gt;Original Post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://brenden.codes/rebuildingupdate-1" rel="noopener noreferrer"&gt;Update #1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://brenden.codes/rebuilding-my-home-on-the-web-update-2" rel="noopener noreferrer"&gt;Update #2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update #3 (You Are Here)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://brenden.codes/rebuilding-my-home-on-the-web-update-4" rel="noopener noreferrer"&gt;Update #4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Last week I hit the point where I felt pretty happy with where things stood, so I shipped the new version of the site to my primary domain! I let it run for a week and then decided to check it in PageSpeed Insights to gauge how successful I was with the changes. &lt;/p&gt;

&lt;p&gt;Previously, this is where the page was sitting. Not super great perf wise.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8pf1vajk5k2hkv2cfght.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8pf1vajk5k2hkv2cfght.png" alt="PageSpeed scores for old version of page: performance: 56, Accessibility: 96, Best Practices: 92, SEO: 100" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now with the new version its doing much better. A small bump in the A11y score to bring that to 100, and an even larger jump on performance. I attribute this mainly to not using the particle background anymore, but nevertheless I'm calling this a win!&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq3ftt08ezmge07mwkv1y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq3ftt08ezmge07mwkv1y.png" alt="PageSpeed scores for new version of page: performance: 100, Accessibility: 100, Best Practices: 92, SEO: 100" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a couple small tweaks I may make here and there, but for now I'm calling this done and starting prep for the next website - my resume. &lt;/p&gt;

</description>
      <category>emptystring</category>
    </item>
    <item>
      <title>Rebuilding My Home on the Web - Update #2</title>
      <dc:creator>Brenden Niedermeyer (he/him)</dc:creator>
      <pubDate>Mon, 14 Nov 2022 12:00:00 +0000</pubDate>
      <link>https://dev.to/nieds/rebuilding-my-home-on-the-web-update-2-2ebb</link>
      <guid>https://dev.to/nieds/rebuilding-my-home-on-the-web-update-2-2ebb</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K1g804OC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1920x1062/3ba346e29e/update-2-intro.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K1g804OC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1920x1062/3ba346e29e/update-2-intro.png" alt="A screenshot of the updated design with gradient and background pattern" width="880" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post is part of a series. You can view the other posts here: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://brenden.codes/rebuilding-my-home-on-the-web"&gt;Original Post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://brenden.codes/rebuildingupdate-1"&gt;Update #1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update #2 (You are here)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://brenden.codes/rebuilding-my-home-on-the-web-update-3"&gt;Update #3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://brenden.codes/rebuilding-my-home-on-the-web-update-4"&gt;Update #4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My current landing page, uses &lt;a href="https://github.com/Wufe/react-particles-js"&gt;react-particles-js&lt;/a&gt; to have an animation running in the background. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D7TqYUTh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://a.storyblok.com/f/104216/1918x1008/8fca1e86d0/update2-particles.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D7TqYUTh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://a.storyblok.com/f/104216/1918x1008/8fca1e86d0/update2-particles.gif" alt="My current website with moving particles in the background" width="880" height="462"&gt;&lt;/a&gt;&lt;br&gt;
I held off on re-implementing this until I was satisfied with the rest of the site because I wasn't ahead 100% sure I would keep it. &lt;/p&gt;

&lt;p&gt;I ultimately decided to do away with the particles for a few reasons: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It made the page design look very busy. It easily draws the eye away from the content of the page and harms the overall experience, in my opinion.&lt;/li&gt;
&lt;li&gt;Keeping it makes the site less accessible. With the particles, I'd have to add extra javascript this time around just to handle users who prefer reduced motion. In other places I can handle this with some straightforward CSS, and while I could &lt;em&gt;probably&lt;/em&gt; do that here too it seemed like a lot of work when users would get a better experience by just not implementing it.
&lt;/li&gt;
&lt;li&gt;Performance. I've noticed in the past that the animations definitely behave differently on different devices. It wasn't horrible, but it was impacting some metrics like &lt;a href="https://web.dev/lcp/"&gt;LCP&lt;/a&gt; on the page. &lt;a href="https://www.youtube.com/watch?v=CYVs9hllqZY"&gt;By not including it, I can ensure better performance across a wider range devices&lt;/a&gt;. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But now the question was, what should replace the particles? Leaving it as it currently stood was a bit boring. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RpeM6ehE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1680x889/e7c883bce2/update2-no-particles.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RpeM6ehE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1680x889/e7c883bce2/update2-no-particles.png" alt="The page with a plain dark background and no particles. " width="880" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I decided to add a little depth via a gradient. This was fairly straightforward to do with tailwind. I just updated the styling of the background to be a gradient instead of a single color.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"
      bg-gradient-to-r 
      from-sky-800 via-amber-100 to-primary-light 
      dark:from-primary-dark dark:via-cyan-700 dark:to-cyan-800"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After adjusting some of the font colors and weights it started to look much better, but was still feeling pretty flat. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---lzH7lmi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1526x609/3b86902f04/update2-gradients.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---lzH7lmi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1526x609/3b86902f04/update2-gradients.png" alt="Light and dark mode of the pages with the new gradients." width="880" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I found a few great SVG backgrounds at &lt;a href="https://heropatterns.com/"&gt;Hero Patterns&lt;/a&gt; and, after adjusting them a bit so they weren't as prominent, added them via CSS to the page. I also decided that instead of just having one, I'll randomly select a pattern on page load and use that. To achieve that I created an array with the names of the patterns and on load, randomly selected the index of one of the patterns.&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="c1"&gt;// done outside of the component since these are static&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;backgrounds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gears&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="s1"&gt;circuit&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="s1"&gt;diamonds&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;


&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;randomNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// further down in the actual component&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;bgPattern&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;backgrounds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;randomNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;backgrounds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;section&lt;/span&gt;
    &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;bgPattern&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;intro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the added texture from the background it looks much better, and not as busy as it did the particles. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gKsWDVXP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1654x894/0bbbe9a827/update2-final.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gKsWDVXP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1654x894/0bbbe9a827/update2-final.png" alt="Final version of the pages with gradient and pattern background on a desktop, tablet, and mobile device. " width="880" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Rebuilding My Home On The Web</title>
      <dc:creator>Brenden Niedermeyer (he/him)</dc:creator>
      <pubDate>Sun, 18 Sep 2022 18:50:46 +0000</pubDate>
      <link>https://dev.to/nieds/rebuilding-my-home-on-the-web-269h</link>
      <guid>https://dev.to/nieds/rebuilding-my-home-on-the-web-269h</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tB32b3Pl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/500x499/6cca4afa3e/why-not.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tB32b3Pl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/500x499/6cca4afa3e/why-not.jpg" alt="Bilbo Baggins meme: &amp;quot;After all, why not? Why shouldn't I rebuild it?&amp;quot;" width="500" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I like using projects to learn new things and keep my skills up to date. Everyone has their own pet projects that they keep coming back to. For some it's a version of a todo app they rebuild in whatever tools their interested in at the moment, for others its their blog, or maybe a game. For me, &lt;a href="https://brenden.fyi"&gt;it's&lt;/a&gt; &lt;a href="https://brenden.codes"&gt;my&lt;/a&gt; &lt;a href="https://brenden.dev"&gt;websites&lt;/a&gt;. Over the last few years, I've built my resume, blog, homepage, and calling card in a variety of tools. The last few weeks I've gotten that itch again, so decided to start yet another rebuild. At the same time the past few years I've really come to appreciate the idea of &lt;a href="https://www.learninpublic.org/v1-principles-learn-in-public.pdf"&gt;learning in public&lt;/a&gt;, but haven't taken part as much in the process as I'd like. So, instead of this post being a "Look at this thing I made!" post, this is more of a "Look at this thing I'm making" post. I'll post my plans here and updates as I progress with learnings I've gathered along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Plan
&lt;/h2&gt;

&lt;p&gt;Over the past couple years, I've slowly started to migrate all of my websites into a monorepo powered by &lt;a href="https://nx.dev"&gt;Nx&lt;/a&gt;. This project will see the completion of that work, pulling all projects under the same repository with tooling that encourages best practices. Here's the planned architecture : &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iiuZo9zb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1265x1027/133fcccac8/architecture.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iiuZo9zb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1265x1027/133fcccac8/architecture.png" alt="architecture diagram of new websites" width="880" height="714"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❗note: these plans could change at anytime. I'll update here if they do. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The three websites will be built in three different front-end frameworks. My blog will be built with Astro (most likely using React within it), mainly because it's the new kid on the block and I'd like to get to know it a bit. The resume will be built with Angular, because even though I don't work with it every day anymore it still has a special place in my heart and I'd like to see the &lt;a href="https://angular.io/guide/standalone-components"&gt;new standalone components&lt;/a&gt; in action and revisit Scully. My homepage will be built with Next because it's currently my daily driver at work and I'd like to strengthen my skills there and work more with the recent ISR tooling. &lt;/p&gt;

&lt;p&gt;Those projects that have more dynamic content (e.g my blog, and online resume) will be using Storyblok as the CMS. Why? To be honest, I use Storyblok in my day to day work. It's great! I'm comfortable with it, but want the chance to explore some of the newer updates they've released since the 2.0 rollout last month in a lower-risk environment. I'm deploying my Next based site to Vercel for the same reason. The other two pages, are planned to be deployed to Netlify. I'm hoping by the end of this I'll get a nice refreshed comparison between what it's like to work with all these tools. In addition to the above I have the other goals in mind: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;standardize my styling to use Tailwind across all projects&lt;/li&gt;
&lt;li&gt;have live previews working within Storyblok, especially for blog posts&lt;/li&gt;
&lt;li&gt;organize components and shared logic better via the libraries (mentioned in the above diagram)&lt;/li&gt;
&lt;li&gt;incorporate A11y testing via end-to-end tests&lt;/li&gt;
&lt;li&gt;add a feature to share interesting articles/books I've read on my homepage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this time I'm not planning any large design change, unless I deem it necessary later on. Simply a rebuild and consolidation while learning a few new tools and I'll be happy. &lt;/p&gt;

&lt;h2&gt;
  
  
  Current Status
&lt;/h2&gt;

&lt;p&gt;All my work can be found on &lt;a href="https://github.com/bniedermeyer/bniedermeyer.github.io/tree/rebuild"&gt;this branch&lt;/a&gt;. I'll probably start opening PRs against it vs blindly pushing changes soon. My main landing page, brenden.dev, is mostly complete and can be found deployed on Vercel &lt;a href="https://brenden-dev.vercel.app/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have no set schedule or timeline, but hope to have everything finished in the next few months while I work on it during my free-time. Here's hoping! Updates will be posted here, unless the update is huge, in which case I may split it off as a separate post.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
      <category>storyblok</category>
      <category>learninpublic</category>
    </item>
    <item>
      <title>CascadiaJS 2021: Building live experiences with Web Components</title>
      <dc:creator>Brenden Niedermeyer (he/him)</dc:creator>
      <pubDate>Wed, 03 Nov 2021 12:58:32 +0000</pubDate>
      <link>https://dev.to/nieds/cascadiajs-2021-building-live-experiences-with-web-components-4e33</link>
      <guid>https://dev.to/nieds/cascadiajs-2021-building-live-experiences-with-web-components-4e33</guid>
      <description>&lt;p&gt;Today is  the first day of &lt;a href="https://2021.cascadiajs.com/"&gt;CascadiaJS 2021&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/GStLeae4F7VIs/giphy-downsized-large.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/GStLeae4F7VIs/giphy-downsized-large.gif" alt="crowd applauding" width="384" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To celebrate, this post will be the first in a series talking about how we built out some of live experiences you will see on the web during the hybrid conference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goals
&lt;/h2&gt;

&lt;p&gt;This year, we had two areas of our live stage that we wanted to update. Our Q&amp;amp;A experience and mirroring the chat in our Discord server (seen here outlined in red). &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rDOjdRd4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1920x1062/7260929028/example.png/m/" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rDOjdRd4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://a.storyblok.com/f/104216/1920x1062/7260929028/example.png/m/" alt="The live conference view for CJS 2021" width="880" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A
&lt;/h3&gt;

&lt;p&gt;The first was our Q&amp;amp;A section. This allowed attendees to submit questions for the speakers, and then vote on whichever ones they really wanted answers to. Last year, this was accomplished with a small React app that was dropped into the stage via an iframe. This worked great, but posed some limitations.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Since it was an iframe, it was difficult to interact with other aspects of the stage. We wanted to wipe the questions each time a new talk started and be aware which users submitted and voted for questions so that users could only vote for a specific question once. This was accomplished with query params passed to the iframe, but overall felt a bit hacky and was prone to error.&lt;/li&gt;
&lt;li&gt;Because we were just using an iframe, we couldn't give any meaningful control around things like styling to the rest of our colleagues building the stage. This meant that if anything needed to change, we would have to open a pr against another project and release that before being able to test it. Not the worst thing, but the back and forth it caused when it came to development just wasn't as efficient as we would have liked.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Discord View
&lt;/h3&gt;

&lt;p&gt;Last year, we hosted our live chat for the conference on Slack. This year we decided to shake things up and use Discord as our digital chat home for the conference. We still wanted to mirror the chat in the livestream channel, but because it's an entirely different platform, we would need to build out functionality similar to last year's. Additionally, we wanted to handle media and text a bit better. Discord allows you to embed gifs and auto-unrolls img links dropped in a chat. Discord can also handle text formatted in Markdown, so we wanted to reflect that in the mirror transcript as well. Like the Q&amp;amp;A section, we also wanted to supply a great base experience, but allow it to be overridden or extended if needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open Source
&lt;/h3&gt;

&lt;p&gt;CascadiaJS is a big believer in &lt;a href="https://github.com/cascadiajs/cascadiajs-2021"&gt;building in public&lt;/a&gt; and helping to share what we learn along the way. Any solution we built, we wanted it usable by the greater community. For this reason, we also decided to build the solutions as individual &lt;a href="https://www.webcomponents.org/introduction"&gt;Web Components&lt;/a&gt;, so they could be used by any JavaScript project, regardless of framework (or lack thereof).&lt;/p&gt;

&lt;h2&gt;
  
  
  How we did it
&lt;/h2&gt;

&lt;p&gt;In the end, we published our Web Components in two separate packages: &lt;code&gt;@cascadiajs/discord-mirror&lt;/code&gt; and &lt;code&gt;@cascadiajs/q-and-a&lt;/code&gt;. Later posts will go more in depth on how we solved specific problems, but here are the tools we ended up using.&lt;/p&gt;

&lt;h3&gt;
  
  
  Abbot
&lt;/h3&gt;

&lt;p&gt;For integrating with Discord and syncing messages we used &lt;a href="https://ab.bot/"&gt;Abbot&lt;/a&gt;. Abbot helps you to build chatbots that work in Discord, Slack, or MS Teams. They take a lot of the pain out of building and configuring your integration with various chat platforms and let you interact with the different chat platforms in a nice, standardized way. They just launched a new feature, Patterns, that let you subscribe to messages within a specific channel that match a pattern. This worked great for our use case as it allowed us to subscribe to the #livestream channel people were chatting in while the talks happened. Read more about how Patterns work &lt;a href="https://blog.ab.bot/archive/2021/11/03/how-cascadiajs-uses-abbot/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stencil
&lt;/h3&gt;

&lt;p&gt;Both of the Web Components themselves were built with &lt;a href="https://stenciljs.com/"&gt;Stencil&lt;/a&gt;. Stencil is great because it lets you work with many tools/concepts you may already be familiar with using in other apps, like JSX, Typescript, and React-style data-binding, while giving you powerful tooling around things like, project and component generations,  state management, and working with the Shadow DOM. Since our components were using the Shadow DOM, we were able to provide a base set of styles, but allow users to override them via &lt;a href="https://css-tricks.com/styling-in-the-shadow-dom-with-css-shadow-parts/"&gt;Shadow DOM Parts&lt;/a&gt;. (More on this in a future post).&lt;/p&gt;

&lt;h3&gt;
  
  
  Firebase
&lt;/h3&gt;

&lt;p&gt;Abbot helped us to get messages out of Discord, Stencil helped us to visualize those messages and allow users to ask questions to the speaker, but how do we go about connect them together? That's where Firebase comes in. With Firebase, we were able to write simple functions to accept the data we needed and load it into a &lt;a href="https://firebase.google.com/docs/database/"&gt;Realtime Database&lt;/a&gt;. The best benefit to this was, thanks to the Firebase SDK, we could subscribe to any changes that would happen in the database within our components and have them reflected in the UI without needing to do repetitive polling.&lt;/p&gt;

&lt;h2&gt;
  
  
  What next?
&lt;/h2&gt;

&lt;p&gt;Like I said earlier, this is the first post in a series I'll be publishing over the next weeks talking about different problems we faced and other learnings to take away from building these components. Some topics will include handling mixed media within messages, allowing customization of the components, providing user choice between different backend solutions, and others. If there's anything specific you want me to cover, reach out and let me know! Meanwhile, if you'd like to see the code for our Web Components, they can be found here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/bniedermeyer/q-and-a"&gt;Q&amp;amp;A&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bniedermeyer/cascadiajs-discord-mirror"&gt;Discord Mirror&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Until then, ENJOY THE CONFERENCE! This really has been a labor of love for the organizer team, and we can't wait to see you all in person and online. If you see me hanging around in Discord or Gather, say hi!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why I got involved with CascadiaJS</title>
      <dc:creator>Brenden Niedermeyer (he/him)</dc:creator>
      <pubDate>Fri, 24 Jul 2020 12:40:32 +0000</pubDate>
      <link>https://dev.to/cascadiajs/why-i-got-involved-with-cascadiajs-2op0</link>
      <guid>https://dev.to/cascadiajs/why-i-got-involved-with-cascadiajs-2op0</guid>
      <description>&lt;p&gt;CascadiaJS is one of my favorite conferences. Having grown up in the Pacific Northwest the conference, which focuses on the community and talent here, has a special place in my heart. Every year I leave the event feeling renewed and excited about the work we do as developers, as well as looking forward to all the great things my fellow attendees will achieve. I’ll be attending again this year remotely on September 1-2, and you should too! Here’s why:&lt;/p&gt;

&lt;h1&gt;
  
  
  The talks are amazing
&lt;/h1&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%2Fbrenden.codes%2Fmedia%2Fwhy-cascadiajs%2FIMG_2786.jpg" 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%2Fbrenden.codes%2Fmedia%2Fwhy-cascadiajs%2FIMG_2786.jpg" alt="speaker on stage discussing code"&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%2Fbrenden.codes%2Fmedia%2Fwhy-cascadiajs%2FIMG_2782.jpg" 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%2Fbrenden.codes%2Fmedia%2Fwhy-cascadiajs%2FIMG_2782.jpg" alt="speaker on stage discussing ableism"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve been attending since 2018 and the one thing that I always look forward to are the talks. These aren’t your usual tech conference talks. In the past I’ve enjoyed talks covering a wide range of topics ranging from how to use machine learning to prevent people from &lt;a href="https://www.youtube.com/watch?v=3wx806HOgnA&amp;amp;feature=emb_title" rel="noopener noreferrer"&gt;hacking a Porg to scream when your build breaks&lt;/a&gt; to &lt;a href="https://www.youtube.com/watch?v=H8crihughSc&amp;amp;feature=emb_title" rel="noopener noreferrer"&gt;building VR experiences on the web&lt;/a&gt;, to &lt;a href="https://www.youtube.com/watch?v=SDdsD5AmKYA&amp;amp;feature=emb_title" rel="noopener noreferrer"&gt;addressing ableism in the developer community&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This year will be no different. There will be talks about &lt;a href="https://2020.cascadiajs.com/speakers/april-speight" rel="noopener noreferrer"&gt;integrating AI with robotics&lt;/a&gt;, &lt;a href="https://2020.cascadiajs.com/speakers/rahat-chowdhury" rel="noopener noreferrer"&gt;building mental health support into our communities&lt;/a&gt;, &lt;a href="https://2020.cascadiajs.com/speakers/pantelis-kalogiros" rel="noopener noreferrer"&gt;how constraints can actually help stimulate creativity in web development&lt;/a&gt;, and &lt;a href="https://2020.cascadiajs.com/speakers/will-klein" rel="noopener noreferrer"&gt;deep dives into the impact of memory leaks&lt;/a&gt; (just to name a few). The talks I see at CascadiaJS blow me away every year and I expect this year to be just the same.&lt;/p&gt;

&lt;h1&gt;
  
  
  The community is top-notch
&lt;/h1&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%2Fbrenden.codes%2Fmedia%2Fwhy-cascadiajs%2FIMG_1114.jpg" 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%2Fbrenden.codes%2Fmedia%2Fwhy-cascadiajs%2FIMG_1114.jpg" alt="CascadiaJS mission statement"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think the picture of the CascadiaJS mission above says it all. Community is the heart of the conference. I always come away from my time at CascadiaJS feeling warm and fuzzy. Everyone in the CJS community is friendly, welcoming and love to support each other in getting better. No matter your experience level you’ll find people who want to chat with you about a huge range of topics and make you and the developer community in the Pacific Northwest better. The CascadiaJS &lt;a href="https://join.slack.com/t/cascadiajs/shared_invite/enQtNzYzMzYxMTc0OTc5LWM0ZDZiZDc5MDgwMmFkODdlZTdiMGE3NjFhYTZmNWVkMWEwMDcxNWE0Nzg5YTcwOGQzZDk0Y2M3ZWRmN2QwNzU" rel="noopener noreferrer"&gt;Slack&lt;/a&gt; has channels where folks can get #virtual-coffee, ask for advice in #mentorship, or just keep each other company while working from home. That magic won’t go away just because the event will be online; the team is even working on ways to recreate the in-person &lt;em&gt;hallway track&lt;/em&gt; that we all know and love.&lt;/p&gt;

&lt;p&gt;A great example of the strength of the CascadiaJS community is the &lt;a href="https://2020.cascadiajs.com/scholarships" rel="noopener noreferrer"&gt;Opportunity Scholarship&lt;/a&gt; program they run. The team wants to ensure that anyone who wants to attend the conference has the ability and offer heavily discounted and free tickets to anyone who is a member of an under-represented minority in tech.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Learn more about the &lt;a href="https://2020.cascadiajs.com/scholarships" rel="noopener noreferrer"&gt;scholarship program and how to apply here!&lt;/a&gt;Want to help support the scholarship program? &lt;a href="https://ti.to/event-loop/cascadiajs-2020/with/scholarship-donation" rel="noopener noreferrer"&gt;Donate here!&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Fun conference events events and swag
&lt;/h1&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%2Fbrenden.codes%2Fmedia%2Fwhy-cascadiajs%2FIMG_2807.jpg" 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%2Fbrenden.codes%2Fmedia%2Fwhy-cascadiajs%2FIMG_2807.jpg" alt="picture of photo booth group"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Past events have ranged from having parties at the Living Computers Museum, renting out entire movie theaters for a special premier, karaoke get togethers and events focusing on mentorship.&lt;/p&gt;

&lt;p&gt;This year will obviously be a bit different because of the remote aspect driven by the global situation with COVID-19, but word has it the team has some great surprises in store.You don't even have to wait until September to join in! There are events planned prior to the conference kick off (including a job fair the day before the conference).&lt;/p&gt;

&lt;p&gt;Did I mention that you still get incredible swag just for buying a ticket? Just because we can't hang out in person doesn't mean we should miss out on all the cool conference stuff! This year all attendees who register before the 24th (that's today!) will get a coveted CascadiaJS hoodie, a bunch of stickers, and other really cool secret surprises in time for the conference. You really don't want to miss out on it, trust me. &lt;/p&gt;

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

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



&lt;/p&gt;

&lt;h1&gt;
  
  
  Want to join the fun?
&lt;/h1&gt;

&lt;p&gt;Like I said, I’m counting down the days until CascadiaJS kicks off on September 1st. Want to grab a ticket so you’re not left out? &lt;a href="https://ti.to/event-loop/cascadiajs-2020/discount/brenden" rel="noopener noreferrer"&gt;Grab one here&lt;/a&gt; (don’t forget to register before the 24th so you get your swag). See you there!&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%2Fbrenden.codes%2Fmedia%2Fwhy-cascadiajs%2FIMG_2812.jpg" 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%2Fbrenden.codes%2Fmedia%2Fwhy-cascadiajs%2FIMG_2812.jpg" alt="conference attendees group photo"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>community</category>
      <category>webdev</category>
      <category>swag</category>
    </item>
    <item>
      <title>Where We Publish Technical Writing</title>
      <dc:creator>Brenden Niedermeyer (he/him)</dc:creator>
      <pubDate>Sun, 19 May 2019 12:40:32 +0000</pubDate>
      <link>https://dev.to/nieds/where-we-publish-technical-writing-5dkg</link>
      <guid>https://dev.to/nieds/where-we-publish-technical-writing-5dkg</guid>
      <description>&lt;p&gt;This year at ng-conf, I took part in the &lt;a href="https://github.com/wesleygrimes/technical-writers-summit"&gt;Technical Writers Summit&lt;/a&gt;. I gave a brief talk where I wanted to talk about different places and strategies for publishing the technical blog posts that all of us attending the event write. As I prepared my talk and thought more on the topic I realized while I could talk about what &lt;em&gt;I&lt;/em&gt; do, it might not be totally representative of what others do. So I threw together a small survey a week or so before the event and gathered as much input on the topic of where we publish, why we choose those places, and other related questions as possible. Here are some takeaways I found after digging into the data:&lt;/p&gt;

&lt;h1&gt;
  
  
  Most post to only one platform
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QlU6gGMz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brenden.codes/media/where-we-publish/how_many_places-4f5ced96-ccf1-40ab-9ccd-2871d55ef5e7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QlU6gGMz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brenden.codes/media/where-we-publish/how_many_places-4f5ced96-ccf1-40ab-9ccd-2871d55ef5e7.png" alt="a graph comparing the number of platforms writers post on"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This first one surprised me a little. With all of the options for people to publish their writing on, I assumed most would spread out across them much like many people do with social media. I suspect this may be due to difficulties cross-publishing to different places (more on this later).&lt;/p&gt;

&lt;h1&gt;
  
  
  Medium is still a powerhouse
&lt;/h1&gt;

&lt;p&gt;Of all the different places that people post to, Medium grabbed the majority of those who only posted in a single place, followed by self-hosted blogs. That’s the same amount of people who say they only post to Medium as everyone who says they post to some combination of platforms combined. Medium was also the most used overall out of all the choices.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0qwg5oc5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brenden.codes/media/where-we-publish/Where_do_you_publish-c7cf6109-bf1d-4b49-8972-a9483bdb3049.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0qwg5oc5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brenden.codes/media/where-we-publish/Where_do_you_publish-c7cf6109-bf1d-4b49-8972-a9483bdb3049.png" alt="A graph comparing all the different combinations of platforms writers publish to"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Akcmdf4G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brenden.codes/media/where-we-publish/where-do-you-post.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Akcmdf4G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brenden.codes/media/where-we-publish/where-do-you-post.png" alt="A graph comparing how many writers choose each platform"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This also makes sense given the common thread in responses of wanting to post where the readers are. If we want people to read what we write to some degree we need to go to them. Right now, a large number of them are on Medium.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pain points
&lt;/h1&gt;

&lt;p&gt;I was also interested in the difficulties that some writers encountered when publishing their work. Code blocks/formatting/highlighting within the blog posts on different platforms was one of the points that were often mentioned. That’s understandable given that on some platforms it’s quite easy to feature blocks of code with the proper highlighting while on others, Medium, for example, you often have to choose between having easily embeddable code blocks without highlighting or managing one or more separate gists to embed code samples the way you would like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FmjyYsWA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brenden.codes/media/where-we-publish/Untitled-4aad7a34-8f92-4650-84cf-8cde0341d6d5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FmjyYsWA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brenden.codes/media/where-we-publish/Untitled-4aad7a34-8f92-4650-84cf-8cde0341d6d5.png" alt="A graph comparing the different pain points writers encounter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another common issue was how difficult it can be for cross-posting between the different platforms. Importing your content for a post is sometimes cumbersome and, in some cases, can drive traffic away from your intended target if not done properly due to the SEO weight of something like DEV.to or Medium vs your own personal blog.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Quick pro-tip: Both DEV.to and Medium allow you to set the &lt;a href="https://unamo.com/blog/general/beginners-introduction-canonical-tag"&gt;canonical url&lt;/a&gt; for posts. If you’re new to cross-posting this is a good place to start.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Most write because they enjoy it
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T7LW6jKp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brenden.codes/media/where-we-publish/Untitled-10f77c86-6404-463d-8b7c-37f2150270c1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T7LW6jKp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brenden.codes/media/where-we-publish/Untitled-10f77c86-6404-463d-8b7c-37f2150270c1.png" alt="A graph showing how many writers are paid vs how many do it as a hobby or to learn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just over 21% of those who responded have been paid for their writing while around 79% say that they write technical posts because it helps their understanding of the concept or because they just enjoy it. That’s fantastic (on both accounts)! I think that’s what makes the technical blogging community great - t’s full of people who want to share their knowledge with others while they develop their own skills.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;This was an interesting exercise. Given the relatively small sample size that responded there are some interesting tidbits of information found in the responses. However, this is just a glimpse into the larger technical blogging community. I think I want to try this again in a year, see if we can grow the number of responses, and get an even better picture of the technical blogging community.&lt;/p&gt;

&lt;p&gt;As promised at my talk, I’ve released the response data for others. You can find the link below. Take a look and see if there are any other takeaways that you can find!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.google.com/spreadsheets/d/12PKxiThkpbgm4L3CdqfBesm4aJ0P_7XoSCsafS_z6Uw/edit?usp=sharing"&gt;https://docs.google.com/spreadsheets/d/12PKxiThkpbgm4L3CdqfBesm4aJ0P_7XoSCsafS_z6Uw/edit?usp=sharing&lt;/a&gt;&lt;/p&gt;

</description>
      <category>technicalwriting</category>
    </item>
    <item>
      <title>Getting Started Building Component Libraries with Angular CLI</title>
      <dc:creator>Brenden Niedermeyer (he/him)</dc:creator>
      <pubDate>Sun, 03 Jun 2018 19:50:50 +0000</pubDate>
      <link>https://dev.to/nieds/getting-started-building-component-libraries-with-angular-cli-4ncj</link>
      <guid>https://dev.to/nieds/getting-started-building-component-libraries-with-angular-cli-4ncj</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J4UkNc5G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AIQ9QA3Sy1kX7XdmZmFwlYg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J4UkNc5G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AIQ9QA3Sy1kX7XdmZmFwlYg.jpeg" alt=""&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/photos/JuFcQxgCXwA?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Samuel Zeller&lt;/a&gt; on &lt;a href="https://unsplash.com/search/photos/package?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the things that’s always had a higher barrier of entry in the Angular ecosystem is creating libraries of components that other Angular apps can use. The Angular team published guidance with things like the &lt;a href="https://docs.google.com/document/d/1CZC2rcpxffTDfRDs6p1cfbmKNLA6x5O-NtkJglDaBVs/edit"&gt;Angular Package Format&lt;/a&gt; and from that the community has created some fantastic tools, like &lt;a href="https://github.com/jvandemo/generator-angular2-library"&gt;generator-angular2-library&lt;/a&gt;, that make it easier. However, there was never a tool that generated opinionated implementations of the Angular Package Format the same way that developers who used the Angular CLI in their normal project workflows were used to.&lt;/p&gt;

&lt;p&gt;With the recent release of version 6 for the Angular CLI, we now have access to tools that can help us build libraries while still taking advantage of other powerful aspects of the CLI, such as schematics, without leaving the workflows we are used to! I will show you how to the CLI to get started building your own component libraries.&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generating a library project with the Angular CLI&lt;/li&gt;
&lt;li&gt;Building components for your library&lt;/li&gt;
&lt;li&gt;Using your library in other applications&lt;/li&gt;
&lt;li&gt;Publishing your library for others to use&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Generating a library project with the Angular CLI
&lt;/h3&gt;

&lt;p&gt;First thing’s first. We need to setup our project. If you don’t have the latest version of the CLI grab it from npm.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now create a new project with the CLI. Nothing new here.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;If you’re used to working with the Angular CLI you might notice a couple changes to the project structure you know and love. The most noticable of which is that the old angular-cli.json is gone and now replaced with a new angular.json file.&lt;/p&gt;

&lt;p&gt;This file is the key to one of the biggest new features in version 6. Now the Angular CLI can create and work with workspaces that contain one or more multiple Angular projects. This angular.json file gives you control over the configuration of each of those projects. This is ultimately what makes building of libraries within the CLI possible because we need handle the building of libraries differently than we normally would for normal Angular apps.&lt;/p&gt;

&lt;p&gt;Ok — so now we know a bit more about how libraries within CLI pojects work; let’s generate the library structure in our project. We do this with the generate command just like we would to create a component, service, module, etc...&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This creates a new /projects directory with a new folder for your library and some example files.&lt;/p&gt;

&lt;p&gt;The files to really take note of here are /src/public_api.ts, ng-package.json, and ng-package.prod.json. These files control the configuration for &lt;a href="https://github.com/dherges/ng-packagr"&gt;ng-packagr&lt;/a&gt; - the library that powers the packaging of your library. I encourage you to check out the project and familiarize yourself with how it works, but here is a quick and dirty overview:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;public_api.ts is the new entry point for your library. If you have any files that you want accessable to consumers of your library (modules, components, etc...) you need to export them here in addition to exporting them from whatever modules are in your library.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;ng-package.json and ng-package.prod.json control the configuration for the packaging process that ng-packagr performs. You can use them to change things like the destination build directory or defining a different entry point for your app. ng-package.json is used during your ng build command and ng-package.prod.json is used when you run ng build --prod. The only difference between these two files right now is that ng-package.json contains a deleteDestPath flag that will delete your destination directory before running a build. This will be helpful during development when you are constantly making changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Protip&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: if your library needs to do something like bundle an overall Sass file, you will need to include something like&lt;/em&gt; &lt;a href="https://github.com/SimplrJS/scss-bundle"&gt;&lt;em&gt;scss-bundle&lt;/em&gt;&lt;/a&gt; &lt;em&gt;in your workflow.&lt;/em&gt; &lt;a href="https://github.com/dherges/ng-packagr/issues/273#issuecomment-345059670"&gt;&lt;em&gt;See here for more information&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Building components for your library
&lt;/h3&gt;

&lt;p&gt;Now we have the general structure for our library setup. It’s time to start building!&lt;/p&gt;

&lt;p&gt;First add &lt;a href="https://material.angular.io/"&gt;Angular Material&lt;/a&gt; to our project.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;“Wait, why are we adding Material to my-app and not my-new-lib?” Good question. The easy answer to that question is that in this case Material is a peer dependency of our library. We don’t want it to be downloaded each time our library is installed somewhere — that can lead to things like huge final bundles when the application is built. Instead we want to mandate that whichever project is using our library needs to also have Material installed as well. For libraries that will be installed and consumed by third parties (hint, hint: ours) you’ll need to add things like Material to the peer depencies. There’s a good discussion about when to use peer vs. normal depencies &lt;a href="https://stackoverflow.com/questions/26737819/why-use-peer-dependencies-in-npm-for-plugins"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Additionaly, the ng add command for Material only works for standard project configuration, i.e. those generated by the ng new command. If you were to run ng add @angular/material --project my-new-lib you would get an error saying so. The schematic that is being run in the background to add Material assumes you are adding it to an existing Angular app and not a library so it won't understand since the structure inside angular.json that is setup for your library.&lt;/p&gt;

&lt;p&gt;Go ahead and add to our peer dependencies now.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Let’s setup the module for our library. First, delete the example files that were generated by the CLI in src/lib and from public_api.ts. Then generate the module.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Since we will want others to consume this module we need to add it to public_api.ts.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;For this example the library will have a component that consists of a button and a badge. Each time the button is clicked the badge will update and show the total number of clicks. For added complexity the component should also emit an event to let any parent component know that the count has changed and what the current count is.&lt;/p&gt;

&lt;p&gt;First generate the component.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Export the component that was just created from our library. Also import the MatBadgeModule and MatButtonModule while you are here.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Also add the component to public_api.ts&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now add logic to the component to handle incrementing the count displayed whenever the button is clicked.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Next we’ll wire up the component to the template.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now we have a component that we want other apps to use! But how do we make sure it works? We’ll handle that next.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using your library in other applications
&lt;/h3&gt;

&lt;p&gt;Alright, we have an awesome library ready for use — but how do we actually use it? There’s a couple of different ways.&lt;/p&gt;

&lt;p&gt;The first is to use it within the application that was generated by the CLI when we first started our work. Remember, the Angular CLI doesn’t just generate a single app anymore; instead it generates what the CLI team refers to as a workspace. This means you can build multiple apps and libraries in the same directory and utilize what you built within other projects in the same workspace.&lt;/p&gt;

&lt;p&gt;Open up tsconfig.json in the root of your workspace. You'll see a paths option that points to a dist/my-new-library directory.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;What this does is allow you to automatically use your library, after it’s been built, in other apps in the same workspace. This works similarly to using libraries installed by npm in that you can just import your components and use in your library. This of course means that you &lt;em&gt;must&lt;/em&gt; build any libraries that your app depends on &lt;strong&gt;before&lt;/strong&gt; you build your app, and will need to rebuild it every time you make a change to the library before those changes will be reflected.&lt;/p&gt;

&lt;p&gt;A sample workflow could work like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now go ahead and build our library, then we will build an example of how to use it using the original app generated in our workspace.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This generates the dist/ directory mentioned eariler. If you open that directory and take a look you'll see that ng-packagr has generated FESM2015, FESM5, and UMD bundles of the library for consumption and generated a types file.&lt;/p&gt;

&lt;p&gt;Now we are ready to use the library in our app!&lt;/p&gt;

&lt;p&gt;Import the MyLibModule in src/app/app.module.ts&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We want to demonstrate that the app is receiving the countChanged events from the library component so implement handleCountChanged() in src/app/app.component.ts.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now add the CounterButtonComponent to src/app/app.component.html. Also add a div that shows the values being emitted from the component.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Let’s see our example app in action! Remember to build your library before serving the app.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Open the browser and you’ll see your component in action!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ExgjDjm7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/p96n22t442irmjb076kw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ExgjDjm7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/p96n22t442irmjb076kw.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using libraries like this is a great way for you to share code between multiple Angular apps in the same workspace. Additionally, if you are building something like a component library you could use the originally generated Angular app to build great working examples for your library.&lt;/p&gt;

&lt;h3&gt;
  
  
  Publishing your library for others to use
&lt;/h3&gt;

&lt;p&gt;So, you’ve built an awesome component library and are using it in your own applications, but what if you want to share it so others can use it in their apps?&lt;/p&gt;

&lt;p&gt;First, if you haven’t published anything on npm before go ahead and sign up.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;After you sign into your npm account, build the library again. This time use the --prod flag so that the Angular CLI will perform some additional steps for optimization.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now move into dist/my-new-library. If you want to test that your package will work in other apps you can link it to your local npm registry.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now create a new Angular workspace and link your library to the project.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the new workspace add preserveSymLinks to angular.json in the options object under projects/test-lib-app/architect/build. This allows the linking of your library to continue working when the app is served.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Use the library in the same way we did eariler and you see that it will work here as well! To remove the linked library you can use an npm remove my-new-library command in the test project and the npm unlink command in the directory of your built library.&lt;/p&gt;

&lt;p&gt;If you are ready to publish your app to npm for others go ahead and run the below command inside of your dist/my-new-library directory.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;From there you can use it as you would any other packages using npm install.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next Steps
&lt;/h3&gt;

&lt;p&gt;Congratulations! You have built your component library with Angular and have published it to npm for others to use. Go forth and build cool libraries to share! For next steps I also highly encourage you to dive into the documentation for &lt;a href="https://github.com/dherges/ng-packagr/issues?q=label%3Adocumentation%20"&gt;ng-packagr&lt;/a&gt; to learn about more advanced topics regarding the library packaging process.&lt;/p&gt;

&lt;p&gt;You can find the code used in the examples in Github &lt;a href="https://github.com/bniedermeyer/component-libraries-with-angular-cli"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>angular</category>
      <category>angular6</category>
      <category>angularcli</category>
    </item>
  </channel>
</rss>
