<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Mike Zornek</title>
    <link>https://mikezornek.com/tags/web-development/</link>
    <description>Recent content in web-development on Mike Zornek</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>mike@mikezornek.com (Mike Zornek)</managingEditor>
    <webMaster>mike@mikezornek.com (Mike Zornek)</webMaster>
    <lastBuildDate>Thu, 12 Jun 2025 10:00:00 -0400</lastBuildDate>
    
	<atom:link href="https://mikezornek.com/tags/web-development/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Becoming an Accessibility Ally: My Early Journey and Resources</title>
      <link>https://mikezornek.com/posts/2025/6/becoming-an-accessibility-ally/</link>
      <pubDate>Thu, 12 Jun 2025 10:00:00 -0400</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2025/6/becoming-an-accessibility-ally/</guid>
      <description>&lt;p&gt;Here is a hard truth: while I &lt;strong&gt;want&lt;/strong&gt; to be viewed as an ally to accessibility, I probably would not score very high if you judged me by my actions. In the past, I&amp;rsquo;ve worked a little extra to find the correct semantic HTML tags to use in various situations. I have included the random image &lt;code&gt;alt&lt;/code&gt; attribute but not much else.&lt;/p&gt;
&lt;p&gt;I had a few peers at my last employment who were more active regarding accessibility. While management or QA rarely prioritized fixes or rejected a PR because of failed accessibility access, there was some effort and discussions in the trenches. I remained mostly on the sidelines, with only one notable unit of work where we evaluated different approaches to keyboard navigation. (This was for a custom, searchable &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt;, which was used for page navigation. I was refactoring it from a messy Alpine implementation to a more cleaned-up LiveView implementation with JS command patterns.)&lt;/p&gt;
&lt;p&gt;Having &lt;a href=&#34;https://mikezornek.com/posts/2025/5/returning-to-self-employment/&#34;&gt;left that job&lt;/a&gt;, the interest in improving my accessibility skills remained, and last week I took action working through Frontend Masters&amp;rsquo; &lt;a href=&#34;https://frontendmasters.com/courses/accessibility-v3/&#34;&gt;Website Accessibility&lt;/a&gt; course by Jon Kuperman.&lt;/p&gt;
&lt;p&gt;In today&amp;rsquo;s post, I&amp;rsquo;ll share some things I learned from the Website Accessibility course and a few tools and resources you can look into if you are interested in leveling up as well.&lt;/p&gt;
&lt;h2 id=&#34;course-review-and-takeaways&#34;&gt;Course Review and Takeaways&lt;/h2&gt;
&lt;p&gt;This is primarily a video course with some limited live code exercises broken down into the following sections:&lt;/p&gt;
&lt;h3 id=&#34;1-accessibility-overview&#34;&gt;1. Accessibility Overview&lt;/h3&gt;
&lt;p&gt;Provided a review of what accessibility is all about, historically and more specifically related to computers and the web. There was a brief review of legal compliance needs and the various web standards that drive accessibility specifications.&lt;/p&gt;
&lt;p&gt;The section ends with installing a screen reader, which will be used in the next section. For me, it was the built-in macOS VoiceOver tool, but &lt;a href=&#34;https://learn-a11y.netlify.app/screen-reader-setup&#34;&gt;other tools were provided&lt;/a&gt; for Windows and Linux.&lt;/p&gt;
&lt;h3 id=&#34;2-semantic-html--assistive-devices&#34;&gt;2. Semantic HTML &amp;amp; Assistive Devices&lt;/h3&gt;
&lt;p&gt;Reviewed image alt text, semantic HTML, the cost and complexity of using &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; elements as intended buttons, and screen reader-only content. We then use our new screen readers to work through some examples, demonstrating how the screen readers consume content using good examples, bad examples, and encouragement to make the bad examples work better.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve used VoiceOver a little in the past. We did some very rudimentary demos of it when I taught the iOS classes for Big Nerd Ranch, but it was never something I leaned on much professionally. The space to use it on some basic exercises helped me greatly. I feel comfortable now, enabling it to walk content and even flip through rotor menus to see how it can navigate.&lt;/p&gt;
&lt;h3 id=&#34;3-managing-focus-and-tab-order&#34;&gt;3. Managing Focus and Tab Order&lt;/h3&gt;
&lt;p&gt;This section reviewed keyboard navigation using tab order to influence the flow, what focus is all about, and how the focus should be visualized. I appreciated the candor of the instructor in reviewing what the accessibility standards ask for regarding focus visuals and how this often feels confrontational to some design teams who want to execute a particular look.&lt;/p&gt;
&lt;h3 id=&#34;4-aria-labels--roles&#34;&gt;4. ARIA Labels &amp;amp; Roles&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA&#34;&gt;Right from MDN&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Accessible Rich Internet Applications (ARIA) is a set of roles and attributes that define ways to make web content and web applications (especially those developed with JavaScript) more accessible to people with disabilities.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this section, the instructor reviewed some examples of ARIA. These specifically relate to me as a web application developer, as I often develop component abstractions that might not fit the standard markup. I can use ARIA roles and labels to decorate my markup to inform assistive devices better.&lt;/p&gt;
&lt;p&gt;There was an exciting review of &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions&#34;&gt;ARIA live regions&lt;/a&gt;, which is a way you can decorate areas of the page that are updating in real-time (like LiveView things). You can even use &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-live#values&#34;&gt;a politeness setting&lt;/a&gt; to help share if the update should interrupt the flow of content or be presented at a break.&lt;/p&gt;
&lt;h3 id=&#34;5-color-contrast&#34;&gt;5. Color Contrast&lt;/h3&gt;
&lt;p&gt;Reviewed how a lack of color contrast can impact people&amp;rsquo;s readability with low vision. This section also talked about how you might choose contrasting colors with intent but get poor outcomes for people with color blindness.&lt;/p&gt;
&lt;p&gt;An example was shared from a Bloomberg article titled &lt;a href=&#34;https://www.bloomberg.com/ux/2021/10/14/designing-the-terminal-for-color-accessibility/&#34;&gt;Designing the Terminal for color accessibility&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://mikezornek.com/posts/2025/6/becoming-an-accessibility-ally/color-vision-deficiency-demo.gif&#34; alt=&#34;An animation comparing our Default Color Scheme to a CVD Color Scheme with a Deuteranopia simulation overlay. This example exposes how the CVD color scheme (right) improved the color accessibility of the &amp;ldquo;up&amp;rdquo; and &amp;ldquo;down&amp;rdquo; market sentiment compared to the default color scheme (left).&#34;&gt;&lt;/p&gt;
&lt;p&gt;Notice how the design chooses red and green with a wanted contrasting visual concept, but when viewed by people with color vision issues, they will not see that contrast. To make it work for those people, choose different colors or offer alternative themes.&lt;/p&gt;
&lt;h3 id=&#34;6-accessibility-tools--testing&#34;&gt;6. Accessibility Tools &amp;amp; Testing&lt;/h3&gt;
&lt;p&gt;The course closes by providing lists and demos of various tools (which I will include in my own resources section below).&lt;/p&gt;
&lt;h3 id=&#34;course-review&#34;&gt;Course Review&lt;/h3&gt;
&lt;p&gt;I enjoyed the course greatly. The video runtime total was about 2.5 hours and I probably spent 5-6 hours working through the content, pausing to read up and try things out. It is an excellent fit for the introduction I was looking for. The exercises were helpful but felt a little too open-ended for me. (I am extremely biased, however, to my own teaching patterns from my Big Nerd Ranch days.)&lt;/p&gt;
&lt;p&gt;I was not an active paying Frontend Masters member before taking the course. I will likely keep it going for a few months and have bookmarked some follow-up course ideas. (I joined back in 2018 when I was first trying to figure out my exit plan from Apple, and took a few React and other web dev courses.)&lt;/p&gt;
&lt;p&gt;In addition to the paid for courses, Frontend Masters has lots of smaller &lt;a href=&#34;https://frontendmasters.com/tutorials/&#34;&gt;tutorials&lt;/a&gt; and &lt;a href=&#34;https://frontendmasters.com/blog/&#34;&gt;blog posts&lt;/a&gt; that might interest you.&lt;/p&gt;
&lt;h2 id=&#34;resources-and-tools&#34;&gt;Resources and Tools&lt;/h2&gt;
&lt;p&gt;With the course behind me, I wanted to apply what I&amp;rsquo;ve learned and start with my blog as soon as possible.&lt;/p&gt;
&lt;p&gt;One of the first tools I used was the &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/&#34;&gt;axe DevTools Firefox extension&lt;/a&gt;. This extension can help point out accessibly concerns (like label-less form elements, color contrast issues, and way more) with good notes on how to approach each problem. The company behind this is &lt;a href=&#34;https://www.deque.com&#34;&gt;Deque&lt;/a&gt; (which is actually where one of my accessibility-fluent peers went to work). A bit of a warning, many of the tools Deque offers have open source availability, but their website kind of steers you to buy the paid-for version, so be prepared to go hunting a bit.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://mikezornek.com/posts/2025/6/becoming-an-accessibility-ally/axe-dev-tools-firefox-extension.webp&#34; alt=&#34;axe DevTools Firefox extension showing a few errors&#34;&gt;&lt;/p&gt;
&lt;p&gt;Another tool I relied on was &lt;a href=&#34;https://rocketvalidator.com&#34;&gt;RocketValidator&lt;/a&gt;. This tool will accept a single URL, validate it and then follow the site links to provide a full review of your site. This is a paid tool, but you can use a very helpful and usable free tier to get started.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://mikezornek.com/posts/2025/6/becoming-an-accessibility-ally/rocket-validator-report-red.webp&#34; alt=&#34;A error filled version of a RocketValidator report.&#34;&gt;&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&#34;https://rocketvalidator.com/s/7b6cc10c-42ed-43f5-9abc-9ac27e3591c7&#34;&gt;initial report for yourself&lt;/a&gt;. (Note: this is the pre-fix version of the report. I&amp;rsquo;ve fixed a ton of those issues.)&lt;/p&gt;
&lt;p&gt;When solving the issues I saw on my public site, I relied on the local HTML validator of the &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/web-developer/&#34;&gt;Web Developer Firefox extension&lt;/a&gt; to help me make sure I was solving the issue. This extension is packed with helpful tools, but today, the &lt;code&gt;Validate Local HTML&lt;/code&gt; tool was invaluable, letting me test local dev changes without publishing.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://mikezornek.com/posts/2025/6/becoming-an-accessibility-ally/firefox-web-developer-extension.webp&#34; alt=&#34;A list of tools offered by the Web Developer extension.&#34;&gt;&lt;/p&gt;
&lt;p&gt;Towards the end of applying my fixes, I also utilized the &lt;a href=&#34;https://wave.webaim.org/&#34;&gt;WAVE (Web Accessibility Evaluation Tool)&lt;/a&gt; provided by the &lt;a href=&#34;https://webaim.org/&#34;&gt;WebAIM organization&lt;/a&gt;. The presentation of structured content and inline overlays of problem areas was helpful—an &lt;a href=&#34;https://wave.webaim.org/report#/https://learn-a11y.netlify.app/screen-reader&#34;&gt;example report&lt;/a&gt; using one of the test pages from the course.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://mikezornek.com/posts/2025/6/becoming-an-accessibility-ally/wave-tool.webp&#34; alt=&#34;WAVE Screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;With most of the accessibility issues resolved, I still had some recommended tools I wanted to try.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://developer.chrome.com/docs/lighthouse/overview&#34;&gt;Lighthouse&lt;/a&gt; is a popular web performance tool. It does include some automated accessibility checks but is way more focused on performance. There are &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/google-lighthouse/&#34;&gt;browser extensions&lt;/a&gt; for Lighthouse, but you can also run it from &lt;a href=&#34;https://pagespeed.web.dev&#34;&gt;the web&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I used some Lighthouse feedback to make some &lt;a href=&#34;https://github.com/zorn/mikezornek.com/blob/2449017836dee2fbc0c91f2d120a8bd80a72aee7/themes/reborn/layouts/partials/head.html#L74&#34;&gt;slight changes&lt;/a&gt; to my image preloads to ultimately help with &lt;code&gt;Largest Contentful Paint (LCP)&lt;/code&gt; timings and drawing the page faster.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://mikezornek.com/posts/2025/6/becoming-an-accessibility-ally/lighthouse.webp&#34; alt=&#34;Lighthouse screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;What also caught my eye was some &lt;a href=&#34;https://github.com/GoogleChrome/lighthouse-ci/&#34;&gt;Lighthouse CI tools&lt;/a&gt;. These can slip into your CI toolchain to generate reports, and enforce performance requirements. I did some &lt;a href=&#34;https://github.com/zorn/mikezornek.com/blob/main/.github/workflows/lighthouse.yaml&#34;&gt;experiments&lt;/a&gt; but would need more time to work correctly. There is even a &lt;a href=&#34;https://github.com/GoogleChrome/lighthouse-ci/blob/main/docs/getting-started.md#the-lighthouse-ci-server&#34;&gt;server&lt;/a&gt; you can run so you might track the status of various performance metrics over time. This could be really powerful for a site of importance, but it is well outside my work scope this week.&lt;/p&gt;
&lt;p&gt;In addition to Lighthouse CI, I also took note of &lt;a href=&#34;https://pa11y.org/&#34;&gt;Pa11y&lt;/a&gt; and its &lt;a href=&#34;https://github.com/pa11y/pa11y-dashboard?tab=readme-ov-file#pa11y-dashboard&#34;&gt;own Dashboard tools&lt;/a&gt; which seem to solve similar automated measurements over time.&lt;/p&gt;
&lt;h2 id=&#34;more-resources&#34;&gt;More Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://webaim.org/&#34;&gt;WebAIM&lt;/a&gt; (web accessibility in mind) has a wonderful collection of articles and resources that can help provide curated and more accessible guidance.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://a11yweekly.com/issues/&#34;&gt;Accessibility Weekly Newsletter&lt;/a&gt; is a weekly dose of web accessibility to help you bring it into your everyday work. Delivered to your inbox each Monday, curated by David A. Kennedy.&lt;/li&gt;
&lt;li&gt;The W3C &lt;a href=&#34;https://www.w3.org/WAI/&#34;&gt;Web Accessibility Initiative (WAI)&lt;/a&gt; develops standards and support materials to help you understand and implement accessibility. This is a general index with lots of information.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&#34;https://www.w3.org/WAI/standards-guidelines/wcag/&#34;&gt;Web Content Accessibility Guidelines (WCAG) docs&lt;/a&gt; can be a little dense but helpful to reference if you are debating different approaches.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;notes&#34;&gt;Notes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;VoiceOver will often read the file names, so if you can avoid gibberish names like &lt;code&gt;20e47595573f720f.jpg&lt;/code&gt;, please do.&lt;/li&gt;
&lt;li&gt;Generally speaking &lt;a href=&#34;https://www.w3.org/WAI/WCAG21/Understanding/conformance#conformance-requirements&#34;&gt;accessibility conformance&lt;/a&gt; is measured and labeled with &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;AA&lt;/code&gt;, and &lt;code&gt;AAA&lt;/code&gt;; and you may see tools like color contrast saying &lt;code&gt;A&lt;/code&gt; level conformance is met but &lt;code&gt;AA&lt;/code&gt; is not.&lt;/li&gt;
&lt;li&gt;I think automation such as CI running these tools and inline component testing of accessibility will be important if a team wants to maintain an accessible site over time. I&amp;rsquo;d similarly recommend bi-yearly (or more often) manual audits to identify improvement opportunities.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;future-enhancements&#34;&gt;Future Enhancements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitHub and other sites provide this cool detection of &lt;code&gt;tab&lt;/code&gt; and immediately show a &lt;code&gt;Skip to Content&lt;/code&gt; link at the top, and when you press &lt;code&gt;Enter,&lt;/code&gt; it jumps to the content. I would love to add that to my blog.&lt;/li&gt;
&lt;li&gt;Many web apps have aligned on showing keyboard shortcuts using &lt;code&gt;?&lt;/code&gt;. I want to consider doing that for future web apps and maybe even search tools for the blog.&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;ve started moving my blog videos into a simple S3 bucket store. I want to figure out a way to provide text transcripts for them.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Every journey begins with a small step. I enjoyed the opportunity to skill up with accessibility, and hope to continue to apply it to future work.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>How to Use a Modern Version of Hugo on Render&#39;s Static Site Service</title>
      <link>https://mikezornek.com/posts/2025/4/modern-hugo-on-render-static-site/</link>
      <pubDate>Thu, 17 Apr 2025 11:03:15 -0400</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2025/4/modern-hugo-on-render-static-site/</guid>
      <description>&lt;p&gt;I host this site at &lt;a href=&#34;https://render.com/&#34;&gt;Render.com&lt;/a&gt;. Specifically, I use Render&amp;rsquo;s &lt;a href=&#34;https://render.com/docs/static-sites&#34;&gt;Static Site product&lt;/a&gt;. It&amp;rsquo;s a good product and free for most usage. It features an auto-configured SSL certificate, global CDN, pull request previews, and many other nice things. I&amp;rsquo;m also paying Render to host some &lt;a href=&#34;https://rankedvote.app/&#34;&gt;Elixir things&lt;/a&gt; and enjoy the simplicity of fewer things to manage&lt;/p&gt;
&lt;p&gt;When you read the docs, Render provides instructions on what to do &lt;a href=&#34;https://render.com/docs/deploy-hugo&#34;&gt;if you are using Hugo&lt;/a&gt; to build your static site. Unfortunately, their version of Hugo is locked and a bit dated as I type this. (I observed version &lt;code&gt;0.124.0&lt;/code&gt; when the current version of Hugo is &lt;code&gt;1.46.5&lt;/code&gt;.) Some other static allow you to set a &lt;code&gt;HUGO_VERSION&lt;/code&gt; environment variable, but sadly Render does not support this.&lt;/p&gt;
&lt;p&gt;Render allows you to supply a custom build command, and I&amp;rsquo;ve taken the opportunity to install an updated version of Hugo per deployment so I can keep it current. Here is the script and some other notes to keep in mind.&lt;/p&gt;
&lt;h2 id=&#34;using-a-custom-build-command&#34;&gt;Using a custom build command&lt;/h2&gt;
&lt;p&gt;You can read more &lt;a href=&#34;https://render.com/docs/deploys#build-command&#34;&gt;official docs&lt;/a&gt; about the build command, but in short, you set it up in the &lt;code&gt;Settings&lt;/code&gt; for your site. Instead of a single command, you can point it to a build shell script from your project&amp;rsquo;s repo.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;render-settings.png&#34; alt=&#34;Render Setting web page&#34; title=&#34;A screenshot of Render&#39;s settings page for the site, showing a line to enter a build command.&#34;&gt;&lt;/p&gt;
&lt;p&gt;My &lt;a href=&#34;https://github.com/zorn/mikezornek.com/blob/63fbcfc5687e778afeafb7d7520a14e0c6cc7437/bin/build.sh#L1&#34;&gt;build script&lt;/a&gt; looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# This script is used by Render to build the app for production deployment.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# set up an exit on error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set -o errexit
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Save the initial directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ORIGINAL_DIR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$PWD&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Install npm dependencies&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Installing npm dependencies...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;npm install --verbose
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Install specific version of Hugo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HUGO_VERSION&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0.145.0&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# Change this to your required version&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Installing Hugo &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;HUGO_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Create directory for Hugo download and installation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/bin&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p /tmp/hugo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd /tmp/hugo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Download and install specific Hugo version&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wget -q https://github.com/gohugoio/hugo/releases/download/v&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;HUGO_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;/hugo_extended_&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;HUGO_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;_Linux-64bit.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tar -xzf hugo_extended_&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;HUGO_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;_Linux-64bit.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Move Hugo to a directory you have permission for&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mv hugo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/bin/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Add the bin directory to PATH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export PATH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/bin:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PATH&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Verify installation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo version
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Return to project directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$ORIGINAL_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Now you can add your Hugo build commands here&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo --logLevel info
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In addition to installing Hugo, I also install some npm packages, including Tailwind and the Tailwind Typography plugin, which I am using for my Hugo template HTML. One thing to keep in mind here is that Render does &lt;a href=&#34;https://render.com/docs/node-version&#34;&gt;honor and expect&lt;/a&gt; a &lt;code&gt;NODE_VERSION&lt;/code&gt; inside your environment settings to hint what version of node to use. This static site was defaulting to a pretty old version of node when I started without a &lt;code&gt;NODE_VERSION&lt;/code&gt; environment variable, and that seems to be &lt;a href=&#34;https://render.com/docs/node-version#history-of-default-nodejs-versions&#34;&gt;based on when the static site service was initialized&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I do a bit of extra logging to help me debug, but overall, this script is pretty straightforward. Make sure to grant execution permissions with &lt;code&gt;chmod a+x build.sh&lt;/code&gt; to the shell script when composing it.&lt;/p&gt;
&lt;h2 id=&#34;inefficiencies&#34;&gt;Inefficiencies&lt;/h2&gt;
&lt;p&gt;Installing Hugo (and node things) for every deployment is excessive and will be charged against my &lt;a href=&#34;https://render.com/docs/build-pipeline#pipeline-minutes&#34;&gt;pipeline minutes&lt;/a&gt;, but for the simple needs of this site, which is published a few times a month I doubt it will add up to anything much. If you want to optimize this, consider Dockerizing the deployment and perhaps even assembling the static content in a continuous integration system like GitHub Actions. (I was planning on that at first, but this build command approach was more straightforward for now.)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>How I Got Rid of My Google-Hosted Web Fonts</title>
      <link>https://mikezornek.com/posts/2025/4/custom-fonts-without-google/</link>
      <pubDate>Tue, 15 Apr 2025 08:19:13 -0400</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2025/4/custom-fonts-without-google/</guid>
      <description>&lt;p&gt;Over the last few weeks, I&amp;rsquo;ve been doing some infrastructure updates to the website, and one of those changes was to drop the use of &lt;a href=&#34;https://fonts.google.com/&#34;&gt;Google&amp;rsquo;s linked web fonts&lt;/a&gt; and instead host custom fonts from my own server in the spirit of improving the privacy of my site visitors.&lt;/p&gt;
&lt;p&gt;Here is how I did it and some of the problems I ran into.&lt;/p&gt;
&lt;h2 id=&#34;picking-your-font&#34;&gt;Picking your font&lt;/h2&gt;
&lt;p&gt;The first custom font I had in mind was &lt;code&gt;Ubuntu&lt;/code&gt;, a bold sans-serif font that I like for my name in the header. You can see samples of this &lt;a href=&#34;https://fonts.google.com/specimen/Ubuntu&#34;&gt;on Google&amp;rsquo;s site&lt;/a&gt;, but to download it, I take advantage of the &lt;a href=&#34;https://gwfh.mranftl.com/fonts/ubuntu&#34;&gt;google-webfont-helper&lt;/a&gt; site, which lets me quickly customize the exact styles I am interested in using and offers me a list of various CSS methods of use. I use the more modern CSS approach, as seen in the following snippet.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/* ubuntu-regular - latin */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@&lt;span style=&#34;color:#66d9ef&#34;&gt;font-face&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;font-display&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;swap&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;font-family&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Ubuntu&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;font-style&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;normal&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;font-weight&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;400&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;src&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;url&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;../fonts/ubuntu-v20-latin-regular.woff2&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;format&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;woff2&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;);&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/* ubuntu-700 - latin */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@&lt;span style=&#34;color:#66d9ef&#34;&gt;font-face&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;font-display&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;swap&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;/* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;font-family&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Ubuntu&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;font-style&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;normal&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;font-weight&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;700&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;src&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;url&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;../fonts/ubuntu-v20-latin-700.woff2&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;format&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;woff2&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;);&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;/* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Source: &lt;a href=&#34;https://github.com/zorn/mikezornek.com/blob/4f3faf6c41540e93ae3cd61e28a7a09bcd08749d/assets/css/main.css&#34;&gt;assets/css/main.css&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Aside:&lt;/strong&gt; I still need to add a proper &lt;a href=&#34;https://assets.ubuntu.com/v1/81e5605d-ubuntu-font-licence-1.0.txt&#34;&gt;license&lt;/a&gt; display for this font usage. That is still forthcoming.&lt;/p&gt;
&lt;h2 id=&#34;using-your-font-with-tailwind&#34;&gt;Using your font with Tailwind&lt;/h2&gt;
&lt;p&gt;The other notable infrastructure update was to make it so I could use Tailwind within my Hugo templates. To reference my font, I use the following &lt;a href=&#34;https://tailwindcss.com/docs/font-family#using-a-custom-value&#34;&gt;Tailwind utility class&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;font-[Ubuntu] text-6xl font-bold&amp;#34;&lt;/span&gt;&amp;gt;{{ site.Title }}&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you want to use a font more broadly, I&amp;rsquo;d recommend &lt;a href=&#34;https://tailwindcss.com/docs/adding-custom-styles#customizing-your-theme&#34;&gt;editing Tailwind configuration&lt;/a&gt; so you can express fonts with better abstractions at call sites, but for this one-off header, this is fine.&lt;/p&gt;
&lt;h2 id=&#34;avoiding-flash-of-unstyled-content-fouc&#34;&gt;Avoiding Flash of Unstyled Content (FOUC)&lt;/h2&gt;
&lt;p&gt;After deploying my new self-hosted fonts, I observed flashes of unstyled content. Specifically, Safari would display the header copy in a serif font and then swap it into Ubuntu. Both Safari and Firefox would flash the new header background texture image as I clicked from page to page.&lt;/p&gt;
&lt;p&gt;I did a little reading and landed on the following solution, which has me use &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/link&#34;&gt;&lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;&lt;/a&gt; elements included in my &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; to help hint to the web rendering systems more early in the drawing process that it will need these resources before the first paint.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;link&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;rel&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;preload&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/fonts/ubuntu-v20-latin-700.woff2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;font&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;font/woff2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;crossorigin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;link&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;rel&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;preload&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/fonts/ubuntu-v20-latin-regular.woff2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;font&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;font/woff2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;crossorigin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;link&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;rel&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;preload&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/images/dark-mosaic.png&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;image&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I think these are working well.&lt;/p&gt;
&lt;p&gt;The font preload &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/preload#cors-enabled_fetches&#34;&gt;explicitly&lt;/a&gt; needs &lt;code&gt;crossorigin&lt;/code&gt; for CORS things, but the image did not, which I find interesting.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I&amp;rsquo;ll probably be doing more with my fonts and the overall design of the site in the coming weeks, but this was a good nugget of progress.&lt;/p&gt;
&lt;h2 id=&#34;resources&#34;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;If you want to avoid hosting a font, consider limiting your options to more likely supported options from the OS. Dreamhost has &lt;a href=&#34;https://www.dreamhost.com/blog/web-safe-fonts/&#34;&gt;a blog post&lt;/a&gt; outlining some good choices for each family style.&lt;/li&gt;
&lt;li&gt;If you want to learn more about fonts (and basic design), I highly recommend &lt;a href=&#34;https://www.goodreads.com/book/show/22251142-the-non-designer-s-design-book&#34;&gt;The Non-Designer&amp;rsquo;s Design Book&lt;/a&gt; by Robin P. Williams. Its teachings stand the test of time.&lt;/li&gt;
&lt;li&gt;I mentioned background textures, and if you are looking for some, check out this &lt;a href=&#34;https://www.transparenttextures.com/&#34;&gt;helpful gallery&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Early Svelte Thoughts</title>
      <link>https://mikezornek.com/posts/2023/7/early-svelte-thoughts/</link>
      <pubDate>Sat, 22 Jul 2023 17:25:51 -0400</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2023/7/early-svelte-thoughts/</guid>
      <description>&lt;p&gt;After more than five years of giving my &lt;strong&gt;full&lt;/strong&gt; attention to Elixir, Phoenix, and LiveView as the primary toolkit I use to build web apps, over the last few weeks, I&amp;rsquo;ve started to sample some other tech stacks, with an initial focus on &lt;a href=&#34;https://svelte.dev&#34;&gt;Svelte&lt;/a&gt; and &lt;a href=&#34;https://kit.svelte.dev/&#34;&gt;SvelteKit&lt;/a&gt;. Here are some early thoughts.&lt;/p&gt;
&lt;h2 id=&#34;why-the-move&#34;&gt;Why the move?&lt;/h2&gt;
&lt;p&gt;This move comes from an ongoing, uneasy feeling that the current LiveView ecosystem lacks the significant and diverse set of choices for libraries that I find myself looking for to help me stand up new UI ideas quickly. LiveView will allow you to build almost anything; you just have to make it yourself.&lt;/p&gt;
&lt;p&gt;I do observe improvements to the core LiveView technologies that may help improve community offerings in the future, but for now, this is how I see it.&lt;/p&gt;
&lt;p&gt;Additionally, there is a particular set of user interactions that I am interested in providing in my user experiences (file uploads, drag and drop, rich animations) that, while possible in LiveView, none-the-less require JavaScript &amp;ndash; and then I ask myself why not just work in that environment from the beginning?&lt;/p&gt;
&lt;p&gt;I also feel like the WebSocket nature of LiveView has some unfortunate tradeoffs regarding offline or flaky network/phone environments. It hasn&amp;rsquo;t been a significant blocker in my production work, but it is always part of the conversation. If I were to build something with a more common mobile web experience target, I&amp;rsquo;d be worried about the WebSocket tradeoff.&lt;/p&gt;
&lt;p&gt;To be clear, Elixir and Phoenix, in general, I&amp;rsquo;m still very positive about. Suppose I were to use a different frontend technology. In that case, I suspect I&amp;rsquo;d still use an Elixir/Phoenix project to provide a GraphQL API, manage jobs, push notifications, emails, and all the other platform needs. I might even still use LiveView for an admin area.&lt;/p&gt;
&lt;h2 id=&#34;why-svelte&#34;&gt;Why Svelte?&lt;/h2&gt;
&lt;p&gt;Similar to an approach that led me to Elixir many years ago, I took some time to review the current state of web frontend technologies. If I were to &lt;a href=&#34;https://survey.stackoverflow.co/2023/#section-admired-and-desired-web-frameworks-and-technologies&#34;&gt;follow the herd&lt;/a&gt; I&amp;rsquo;d probably pick React and/or Next.js, but there was just something special about Svelte for me.&lt;/p&gt;
&lt;p&gt;A few notable things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First off, Svelte is a component system and SvelteKit is a web framework.&lt;/li&gt;
&lt;li&gt;Svelte components are compiled and executed in the browser space using standard JavaScript. There is no typical React-like runtime, and the code generated is much leaner than the historic SPA JavaScript bundle sizes.&lt;/li&gt;
&lt;li&gt;You can do server-side rendering to provide SEO-friendly HTML for non-authenticated pages.&lt;/li&gt;
&lt;li&gt;The style of building Svelte components is light and approachable.&lt;/li&gt;
&lt;li&gt;There are significant &lt;a href=&#34;https://svelte.dev/docs/svelte-motion&#34;&gt;animation tools&lt;/a&gt; within Svelte to provide a dynamic presentation of UI elements.&lt;/li&gt;
&lt;li&gt;The Svelte project and community seem lively and are not overpowered by an individual corporation.&lt;/li&gt;
&lt;li&gt;The technology is a little on the younger side, which does hamper the community library interest that kicked off this search, but I&amp;rsquo;m seeing enough and seeing good momentum that I think I&amp;rsquo;ll be happy.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;store&lt;/code&gt; model for reactive data seems well structured.&lt;/li&gt;
&lt;li&gt;There was a great set of &lt;a href=&#34;https://learn.svelte.dev/tutorial/welcome-to-svelte&#34;&gt;interactive tutorials&lt;/a&gt; that helped me get stated. Afterwards I also worked through the &lt;a href=&#34;https://fireship.io/courses/sveltekit/&#34;&gt;Fireship course&lt;/a&gt; (though I&amp;rsquo;m not sure I&amp;rsquo;d recommend it).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A few negative tradeoffs and concerns on my mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generally speaking, I do not love the JavaScript ecosystem. I&amp;rsquo;ve tried to avoid it as much as possible over the last 15+ years (avoiding it with ease during my Apple time and avoiding it a lot during my Elixir time).&lt;/li&gt;
&lt;li&gt;Stale &lt;code&gt;npm&lt;/code&gt; projects can get dangerous quickly as modules go missing or dependency issues are introduced. Even working on the just released Fireship course, I hit issues trying to deploy; though this was more an experimental Firebase deploy thing than a Svelte thing; but it speaks to my worries of &lt;code&gt;npm&lt;/code&gt; in general.&lt;/li&gt;
&lt;li&gt;The lack of testing tools in the standard SvelteKit project template is a little worrisome.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My next steps are to wireframe a new project idea I&amp;rsquo;ve been pondering and then get hacking to see how I like it. You can only do so many tutorials.&lt;/p&gt;
&lt;h2 id=&#34;learn-one-new-language-a-year&#34;&gt;Learn one new language a year.&lt;/h2&gt;
&lt;p&gt;This Svelte experiment is also good for my consulting/career. It&amp;rsquo;s been harder to find regular consulting work, and expanding my technical skillset might lead to a few more opportunities.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve always promoted the idea of learning one new language a year, even when you will not be applying them right away. In 2021 it was Rust, and in 2022 it was event sourcing. It feels like 2023 is the year of Svelte.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Is WebKit Sabotaging the Future of the Open Web?</title>
      <link>https://mikezornek.com/posts/2020/7/webkit-feature-development-and-privacy/</link>
      <pubDate>Mon, 06 Jul 2020 17:10:19 -0400</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2020/7/webkit-feature-development-and-privacy/</guid>
      <description>&lt;p&gt;This didn&amp;rsquo;t get much press at the time, but during WWDC the WebKit team listed &lt;a href=&#34;https://webkit.org/tracking-prevention/&#34;&gt;a bunch of web technologies they will apparently not be implementing&lt;/a&gt; in the name of privacy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fingerprinting involves measuring the uniqueness of static device configuration (e.g. built-in hardware), dynamic device or browser configuration (e.g. user settings or installed peripherals), and user browsing data (e.g. checking which sites the user is logged in to, so-called login fingerprinting).&lt;/p&gt;
&lt;p&gt;WebKit’s first line of defense against fingerprinting is to not implement web features which increase fingerprintability and offer no safe way to protect the user. Here are some examples of features we have decided to not implement in part due to fingerprinting concerns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Web Bluetooth&lt;/li&gt;
&lt;li&gt;Web MIDI API&lt;/li&gt;
&lt;li&gt;Magnetometer API&lt;/li&gt;
&lt;li&gt;Web NFC API&lt;/li&gt;
&lt;li&gt;Device Memory API&lt;/li&gt;
&lt;li&gt;Network Information API&lt;/li&gt;
&lt;li&gt;Battery Status API&lt;/li&gt;
&lt;li&gt;Ambient Light Sensor&lt;/li&gt;
&lt;li&gt;HDCP Policy Check extension for EME&lt;/li&gt;
&lt;li&gt;Proximity Sensor&lt;/li&gt;
&lt;li&gt;WebHID&lt;/li&gt;
&lt;li&gt;Serial API&lt;/li&gt;
&lt;li&gt;Web USB&lt;/li&gt;
&lt;li&gt;Geolocation Sensor (background geolocation)&lt;/li&gt;
&lt;li&gt;User Idle Detection&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Just to be clear, I am a privacy advocate. I use DuckDuckGo. I use Firefox. I block ads. I encrypt my DNS lookups. I&amp;rsquo;m building &lt;a href=&#34;https://mikezornek.com/projects/guildflow/&#34;&gt;a privacy-focused tool for meetups.&lt;/a&gt; And with all that said, this worries me.&lt;/p&gt;
&lt;p&gt;Right now, many mobile developers would argue that for a rich user experience you need to build a native app and I would agree, at least I would as of today.&lt;/p&gt;
&lt;p&gt;But if I&amp;rsquo;m reading the tea leaves right, and history is a model to follow, what requires &amp;ldquo;native device&amp;rdquo; code today will be possible in the web browser of the future. &lt;a href=&#34;https://webassembly.org/&#34;&gt;WebAssembly&lt;/a&gt; shows great early promise in providing rich cross-platform code opportunities. If you are a 1Password user like me, &lt;a href=&#34;https://blog.1password.com/1password-x-may-2019-update/&#34;&gt;you are probably already enjoying some WebAssembly&lt;/a&gt; today.&lt;/p&gt;
&lt;p&gt;However, to build rich user experiences on a mobile device using WebAssembly or inside a normal web app requires access to the sensors and systems of that device. With this collective blocking of access (along with the &lt;a href=&#34;https://mjtsai.com/blog/2020/06/16/hey-rejected-from-the-app-store/&#34;&gt;lack of side loading options&lt;/a&gt; on iOS and the &lt;a href=&#34;https://en.wikipedia.org/wiki/Firefox_for_iOS&#34;&gt;ban of non-WebKit rendering in App Store apps&lt;/a&gt;) Apple has positioned their own native and financial interests over the favor of an open web.&lt;/p&gt;
&lt;p&gt;Why can&amp;rsquo;t the WebKit developer energy be spent on building these great new APIs and connect them with user empowering privacy tools. A great example of what I mean is website location tracking. If a website wants access you your location (for say driving directions) you can grant it access. I don&amp;rsquo;t understand why a similar approach could not be applied for things like Web Bluetooth access or Proximity sensor access.&lt;/p&gt;
&lt;p&gt;I applaud many of the privacy decisions the WebKit team has made over the past couple of years, but this one feels wrong.&lt;/p&gt;
&lt;p&gt;When I was learning to program in the late 90s we had another &lt;a href=&#34;https://en.wikipedia.org/wiki/United_States_v._Microsoft_Corp.&#34;&gt;big platform vendor who sabotaged the web browser market&lt;/a&gt; for their own interests and I do not want a repeat.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Website Revamp</title>
      <link>https://mikezornek.com/posts/2019/12/website-revamp/</link>
      <pubDate>Tue, 17 Dec 2019 14:01:51 -0500</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2019/12/website-revamp/</guid>
      <description>&lt;p&gt;At the end of November I took a few days and revamped this site. Let me know if you spot any issues or typos. Thanks!&lt;/p&gt;
&lt;h2 id=&#34;whats-new&#34;&gt;What&amp;rsquo;s New&lt;/h2&gt;
&lt;p&gt;I rebuilt, from scratch, the &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; theme code the site uses, wanting to own the site in both design as well as content.&lt;/p&gt;
&lt;p&gt;I added a small bit of color and branding to the main header navigation. I&amp;rsquo;m still big on simple page designs but also feel like returning to a blog post after being here before should have some sense of branding / nostalgia.&lt;/p&gt;
&lt;p&gt;New section, &lt;a href=&#34;https://mikezornek.com/for-hire/&#34;&gt;For Hire&lt;/a&gt;. To date I&amp;rsquo;ve hosted a simple company site at zornlabs.com. It was never much but when considering the idea of building out a project portfolio there it just felt like I was spreading myself too thin across multiple sites. I think for now it&amp;rsquo;s just easier and more productive to focus on a single site to sell me and my services better.&lt;/p&gt;
&lt;p&gt;New section, &lt;a href=&#34;https://mikezornek.com/projects/&#34;&gt;Projects&lt;/a&gt;. Wanting to sell my consulting services, it&amp;rsquo;s important to have a portfolio of some kind and the new Project section serves to do that. For now each project has a short description and accompany video file. I hope to expand it more in the future with some open source efforts.&lt;/p&gt;
&lt;p&gt;Events section renamed &lt;a href=&#34;https://mikezornek.com/talks/&#34;&gt;Talks&lt;/a&gt;. Still not sure if this is the best name but it does describe the goal of the section, to help document and list the various event and conference talks I&amp;rsquo;ve done. The fact it additionally list conferences I&amp;rsquo;m attending is a little verbose, but does help color what I&amp;rsquo;m interested in and excited about.&lt;/p&gt;
&lt;p&gt;The site is now open source, &lt;a href=&#34;https://github.com/zorn/mikezornek.com&#34;&gt;available on GitHub&lt;/a&gt; for all to check out.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>New Year, New Site</title>
      <link>https://mikezornek.com/posts/2019/1/new-year-new-site/</link>
      <pubDate>Tue, 01 Jan 2019 19:51:21 -0500</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2019/1/new-year-new-site/</guid>
      <description>&lt;p&gt;Happy New Year everyone! Hope everyone had a nice break and is recharged for the new year.&lt;/p&gt;
&lt;p&gt;While most of my own break was quiet I did have one side project, rebuilding this website. It&amp;rsquo;s now hosted through a toolchain that includes &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;, a static site generator written in Go, &lt;a href=&#34;https://github.com/&#34;&gt;GitHub&lt;/a&gt;, &lt;a href=&#34;https://circleci.com/&#34;&gt;CircleCI&lt;/a&gt; and &lt;a href=&#34;https://www.linode.com/&#34;&gt;Linode&lt;/a&gt;, replacing the previous WordPress setup.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have nothing against WordPress, but it was overkill for my own needs and I generally like the idea of keeping my server lean, and a static site makes that easier.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The setup is very similar to my previous build of the &lt;a href=&#34;http://phillycocoa.org/&#34;&gt;PhillyCocoa&lt;/a&gt; website. The theme is not custom like PhillyCocoa, but a hack job on the &lt;a href=&#34;https://themes.gohugo.io/hugo_theme_pickles/&#34;&gt;Pickles&lt;/a&gt; theme. It&amp;rsquo;ll do for now but is as a good a base as any.&lt;/p&gt;
&lt;p&gt;If you utilize the &lt;a href=&#34;http://mikezornek.com/index.xml&#34;&gt;RSS feed&lt;/a&gt; for this site you might want to resubscribe. I&amp;rsquo;ve setup some redirects for old feed paths but other formats that WordPress provided (like ATOM) are not currently supported.&lt;/p&gt;
&lt;p&gt;Similarly I&amp;rsquo;ve updated my Micro.Blog to use my own domain now, so its &lt;a href=&#34;http://microblog.mikezornek.com/feed.xml&#34;&gt;RSS feed&lt;/a&gt; is updated as well.&lt;/p&gt;
&lt;p&gt;Feels good to check this project off the list. Hopefully it will encourage some more writing in the future. Stay tuned.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Closing Thoughts on Big Nerd Ranch’s Front End Web Class</title>
      <link>https://mikezornek.com/posts/2016/10/closing-thoughts-on-big-nerd-ranchs-front-end-web-class/</link>
      <pubDate>Thu, 13 Oct 2016 01:48:24 +0000</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2016/10/closing-thoughts-on-big-nerd-ranchs-front-end-web-class/</guid>
      <description>&lt;p&gt;I posted a &lt;a href=&#34;http://mikezornek.com/2016/10/02/greetings-from-the-ranch/&#34;&gt;few&lt;/a&gt; &lt;a href=&#34;http://mikezornek.com/2016/10/05/mid-week-checkin/&#34;&gt;thoughts&lt;/a&gt; while I was attending the &lt;a href=&#34;https://training.bignerdranch.com/classes/front-end-essentials&#34;&gt;Front End Web class&lt;/a&gt; last week and I figured I’d put a cap on it with some final thoughts.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Disclaimer: If you happen to find this post and don’t know, I do in fact work for Big Nerd Ranch, so yes I’m partial but these are still my honest opinions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;who-is-this-class-for&#34;&gt;Who is this class for?&lt;/h2&gt;
&lt;p&gt;Like other BNR books and classes, there is an expectation of some experience. You don’t need to be an expert by any means for this class but you should be comfortable with the basics of web design, hosting and how the web works. If you are looking for these beginner skills I’d recommend &lt;a href=&#34;https://www.codeschool.com/&#34;&gt;Code School&lt;/a&gt; and/or &lt;a href=&#34;https://www.codecademy.com&#34;&gt;Code Academy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With the basics taken care of, this class provides an accelerated but thorough tour of modern web development and the toolchains that you need to know. The class is great for people like myself, who have a history of web development but have been out of the game for a few years or mostly focused on the backend systems. Others who would find value include those who are looking to jumpstart a new web skill set for a new job or project.&lt;/p&gt;
&lt;p&gt;Having a full week to escape the distractions of work and personal obligations really enables you to focus on the class at hand. Combine this with guided lectures and an experienced instructor to answer questions and discuss patterns, really elevates the value to “priceless”.&lt;/p&gt;
&lt;h2 id=&#34;the-syllabus&#34;&gt;The Syllabus&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;http://mikezornek.com/2016/10/05/mid-week-checkin/&#34;&gt;table of contents titles&lt;/a&gt; don’t really do justice to the details of each chapter. In total we build four separate projects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first had us work with HTML5, CSS and JavaScript to do a moderately complex layout of a slideshow like page that included animations, responsive layout and modern markup techniques.&lt;/li&gt;
&lt;li&gt;The second project was a Coffee Order system the helped us use HTML5 forms, Bootstrap styles, and JavaScript to communicate with a backend via AJAX.&lt;/li&gt;
&lt;li&gt;The third project was a chat app, that utilized web sockets. For this app we not only built the front end but the backend too, in Node.js.&lt;/li&gt;
&lt;li&gt;The fourth and final project was an &lt;a href=&#34;http://emberjs.com/&#34;&gt;EmberJS&lt;/a&gt; app that would have us catalog monster sightings. Ember is a big framework but I think the book does a fair introduction. We got to work with a relationship of models, and executed all the big features.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I thought the chapter and project progression went really well. There are some who might prefer to end with &lt;a href=&#34;https://angularjs.org/&#34;&gt;Angular&lt;/a&gt; or &lt;a href=&#34;https://facebook.github.io/react/&#34;&gt;React&lt;/a&gt; instead of Ember but the good thing to know is the early class concepts give you a great JavaScript foundation to build on so you’ll be empowered to experiment with all of those projects and more over time.&lt;/p&gt;
&lt;p&gt;That is a core value of Big Nerd Ranch classes that I really agree with. They teach you from the bottom up so you can understand how things work and not just how to assemble/configure things.&lt;/p&gt;
&lt;h2 id=&#34;the-extras&#34;&gt;The Extras&lt;/h2&gt;
&lt;p&gt;There is lots of open lab time at night. You are encouraged to bring a side project to work on. While I did make some progress on my own project, an Ember Wiki project (I have some basic models and forms working, all backed up my a Firebase persistence layer), I did have to dedicate some lab time to the book itself to make sure I kept up.&lt;/p&gt;
&lt;p&gt;In the afternoons we’d have time for a walk around the resort and on some of the days we even arranged for a shuttle van to take us to some of the exhibits, like the &lt;a href=&#34;http://www.callawaygardens.com/things-to-do/attractions/birds-of-prey&#34;&gt;Birds of Prey&lt;/a&gt; and the &lt;a href=&#34;http://www.callawaygardens.com/things-to-do/attractions/day-butterfly-center&#34;&gt;Butterfly Center&lt;/a&gt;. Considering how focused we are during the class, these excursions are very welcome and a great way to clear your head and get a second wind.&lt;/p&gt;
&lt;h2 id=&#34;final-thoughts&#34;&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;If you want to learn a new technology, in this case Front End Web Development, and in particular if there is a time-sensitive nature to your needs it’s hard to imagine a better environment than a Big Nerd Ranch class. The ticket price does include lodging and food for the week so keep that in mind when shopping around or putting together a formal company request. If you have any questions, feel free to contact &lt;a href=&#34;https://www.bignerdranch.com/contact/&#34;&gt;training support&lt;/a&gt;. They’ll be happy to help you out.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Greetings, from the Ranch</title>
      <link>https://mikezornek.com/posts/2016/10/greetings-from-the-ranch/</link>
      <pubDate>Mon, 03 Oct 2016 02:08:59 +0000</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2016/10/greetings-from-the-ranch/</guid>
      <description>&lt;p&gt;One of the great perks of working at &lt;a href=&#34;https://www.bignerdranch.com/&#34;&gt;Big Nerd Ranch&lt;/a&gt; is that you are allowed to take one Big Nerd Ranch class a year. This week I’m taking the &lt;a href=&#34;https://training.bignerdranch.com/classes/front-end-essentials&#34;&gt;Front End Web class&lt;/a&gt;, and am really looking forward to it.&lt;/p&gt;
&lt;p&gt;At nights we are encouraged to work on a side project to help practice what we are learning in the day. I think I’m going to work on a wiki app — with a few touches that I myself have an itch for, drag and drop image uploads, code syntax coloring, and more.&lt;/p&gt;
&lt;p&gt;I’ll check in later through the week. Wish me luck.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Philly CocoaHeads Website Relaunch Project</title>
      <link>https://mikezornek.com/posts/2015/2/philly-cocoaheads-website-relaunch-project/</link>
      <pubDate>Sun, 22 Feb 2015 23:37:27 +0000</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2015/2/philly-cocoaheads-website-relaunch-project/</guid>
      <description>&lt;p&gt;I haven’t had an active side project in the last few months. When asked I would tell people &lt;a href=&#34;http://mikezornek.com/2015/01/19/my-new-job-with-the-big-nerd-ranch/&#34;&gt;looking for a new job&lt;/a&gt; &lt;strong&gt;was&lt;/strong&gt; my side project. Now that I have that new job search (and my &lt;a href=&#34;http://mikezornek.com/2014/12/31/girl-develop-it-introduction-to-ios-development/&#34;&gt;Girl Develop It class&lt;/a&gt; behind me it’s time to kick something off; we’re going to rebuild the Philly CocoaHeads website!&lt;/p&gt;
&lt;p&gt;When I took over the local chapter of CocoaHeads here in Philly (back in 2010 or so) the previous organizer had a Ruby/Markdown publish system setup. It was kind of neat but involved a lot of setup on the client box to get up and running. I had a few people posting to the site so rather than set up that system on each individual’s box I opted for WordPress. The WordPress site has done ok for us but we’ve been growing a ton and doing a lot more over the last year (workshops, video capture of meeting presentations). I’d love to start to centralize things like keeping track of our members and our money, overall there is a ton that could be automated and it’s time to make it happen.&lt;/p&gt;
&lt;p&gt;I don’t want to do this alone and I also would love to start documenting the project as it unfolds. To get started we have a brainstorm session scheduled during &lt;a href=&#34;http://www.meetup.com/PhillyCocoaHeads/events/219346913/&#34;&gt;Side Project Saturday&lt;/a&gt;. If you want to participate please consider stopping by. If you can’t stop by, but want to participate, &lt;a href=&#34;mailto:zorn@phillycocoa.org&#34;&gt;let me know&lt;/a&gt; and maybe we can setup a Google Hangout call-in option. To capture notes I’m going to use Trello. The &lt;a href=&#34;https://trello.com/b/zCQkG0Lg/website-relaunch-brainstorm&#34;&gt;board is live&lt;/a&gt; and open to the public. (You will need to login with a Trello account to edit.) Feel free to start to document your ideas today.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Early Ember.js Thoughts</title>
      <link>https://mikezornek.com/posts/2013/2/early-ember-js-thoughts/</link>
      <pubDate>Tue, 05 Feb 2013 17:03:16 +0000</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2013/2/early-ember-js-thoughts/</guid>
      <description>&lt;p&gt;Over the last three weeks, I’ve been slowly picking up &lt;a href=&#34;http://emberjs.com/&#34;&gt;Ember.js&lt;/a&gt; while helping some colleagues with a project. It’s pretty interesting tech and I’d like to share some early thoughts.&lt;/p&gt;
&lt;h2 id=&#34;what-is-ember&#34;&gt;What is Ember?&lt;/h2&gt;
&lt;p&gt;To be frank, I don’t think the &lt;a href=&#34;http://emberjs.com&#34;&gt;Ember homepage&lt;/a&gt; does a very good job of explaining Ember. It features terms like “less code” and “developer ergonomics,” which are too much like “marketing speak” for me.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How I view Ember.&lt;/strong&gt; Normally with a web app, you (as a user) will go page to page, sometimes viewing data and then sometimes editing data with forms. That’s what I’ll call a form-based web app. Sometimes you might want a bit of AJAX in these form-based web apps and, to get that, you’ll typically grab a DOM element and manually shove in a bunch of jQuery when needed, including direct commands and event callbacks. This process can work, but the more AJAX and client side stuff you add, the messier you can make things.&lt;/p&gt;
&lt;p&gt;Then there is a class of web apps which work as one-page apps, where all interaction and DOM changes happen on the fly, without moving from page to page. Data is sent to and requested from the server in the background. Think of how &lt;a href=&#34;http://gmail.com&#34;&gt;Gmail&lt;/a&gt; and &lt;a href=&#34;https://trello.com/&#34;&gt;Trello&lt;/a&gt; work.&lt;/p&gt;
&lt;p&gt;For me, Ember.js is all about giving you the toolchain to provide those types of dynamic, one-page web app experiences. Ember.js is a full stack, client-side, JavaScript-based MVC framework. The main objects you’ll work with client-side in the browser include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Routers, which match the requested URL to controllers. They also ensure that the client URL is updated to allow the user to bookmark the different states of your app.&lt;/li&gt;
&lt;li&gt;Models, to define your business nouns and store/retrieve user data.&lt;/li&gt;
&lt;li&gt;Controllers, which handle actions and pass model data to the views.&lt;/li&gt;
&lt;li&gt;Views to connect user events like clicks and taps to controller actions.&lt;/li&gt;
&lt;li&gt;Templates to describe the HTML on screen.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;some-notable-features&#34;&gt;Some Notable Features&lt;/h2&gt;
&lt;h3 id=&#34;bindings&#34;&gt;Bindings&lt;/h3&gt;
&lt;p&gt;If you’ve done AJAX work before, you might recognize that knowing what to update in the DOM can be a nightmare as the app state changes on a given page. Ember is particularly good at dealing with this, and as you build your HTML templates, the substitution hashes like &lt;code&gt;{{ name }}&lt;/code&gt; for a person’s name not only are substituted for the real value on the first render, but everything is always kept up-to-date with an internal bindings system. This, combined with calculated attributes, really takes a lot of stress off the developer, in terms of keeping the app state in sync with the UI state.&lt;/p&gt;
&lt;h3 id=&#34;persistence&#34;&gt;Persistence&lt;/h3&gt;
&lt;p&gt;For actually persisting the data, there is the &lt;a href=&#34;https://github.com/emberjs/data&#34;&gt;ember-data project&lt;/a&gt; which will let you connect and map your client-side Ember models to REST endpoints. If you are using Rails, there are a bunch of gems that can really help to simplify this while providing all the serialization and API endpoints you’ll need. For more info, see &lt;a href=&#34;http://reefpoints.dockyard.com/ember/2013/01/07/building-an-ember-app-with-rails-api-part-1.html&#34;&gt;this article&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;sharp-edges&#34;&gt;Sharp Edges&lt;/h2&gt;
&lt;p&gt;As of this writing, Ember itself is version &lt;code&gt;1.0.0-pre-4&lt;/code&gt; and &lt;code&gt;ember-data&lt;/code&gt; is officially considered alpha quality. There is an upcoming &lt;a href=&#34;http://www.embercamp.com/&#34;&gt;Ember Camp&lt;/a&gt;, which hopes to see continued progress towards an official 1.0 release. Keep an eye on the &lt;a href=&#34;http://emberjs.com/blog/&#34;&gt;Ember blog&lt;/a&gt; for more info. I do believe things have settled down to a point where there is value for people who want to get started with Ember and get their hands dirty. As to “production ready” — well, that will greatly depend on the needs of your application and your comfort with working around some sharp edges.&lt;/p&gt;
&lt;h2 id=&#34;getting-started&#34;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;If you’d like to get started with Ember, in addition to the &lt;a href=&#34;http://emberjs.com/&#34;&gt;main website&lt;/a&gt;, which has some nice and &lt;a href=&#34;http://emberjs.com/guides/&#34;&gt;ever-improving documentation&lt;/a&gt;, I’d also recommend:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://peepcode.com/products/emberjs&#34;&gt;PeepCode’s Fire Up Ember&lt;/a&gt; – Brand new, up-to-date, and very focused on the Ember stack. Well worth the $12.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://trek.github.com/&#34;&gt;An Ember.js tutorial by Trek&lt;/a&gt; – Walked through this myself when I got started. It helped a lot.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://reefpoints.dockyard.com/ember/2013/01/07/building-an-ember-app-with-rails-api-part-1.html&#34;&gt;Brian Cardarella’s Building an Ember app with RailsAPI&lt;/a&gt; – Great walkthrough about starting an Ember app that will use Rails for persistence.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are in Philly, also consider stopping by the &lt;a href=&#34;http://www.meetup.com/Emberjs-Philly/&#34;&gt;local Ember Meetup&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Researching New Web Tools</title>
      <link>https://mikezornek.com/posts/2012/8/researching-new-web-tools/</link>
      <pubDate>Fri, 31 Aug 2012 03:12:52 +0000</pubDate>
      <author>mike@mikezornek.com (Mike Zornek)</author>
      <guid>https://mikezornek.com/posts/2012/8/researching-new-web-tools/</guid>
      <description>&lt;p&gt;I’ve been spec’ing out this app idea off and on for a few months. At first I was going to do it on the Mac, but, as time passed, I decided to make it a web app in the newer style instead. Not a “present form, hit submit, view results” kind of thing, but something that is always saving and receiving messages from the server — very dynamic.&lt;/p&gt;
&lt;p&gt;I’m actually blessed that there are a number of great web tools, libraries, and frameworks to choose from these days. One great overview I read last night was &lt;a href=&#34;http://blog.stevensanderson.com/2012/08/01/rich-javascript-applications-the-seven-frameworks-throne-of-js-2012/&#34;&gt;Rich JavaScript Applications – the Seven Frameworks&lt;/a&gt; by Steven Sanderson. It does a great job listing and categorizing some of the more popular choices out there. New to me on the list was Meteor, and I consider &lt;a href=&#34;http://www.meteor.com/screencast&#34;&gt;its video&lt;/a&gt; a must-see.&lt;/p&gt;
&lt;p&gt;I’m still getting my head around many of these things. My general battle plan is to continue reading and playing with the example code of my &lt;a href=&#34;http://pragprog.com/book/tbcoffee/coffeescript&#34;&gt;CoffeeScript book&lt;/a&gt; (which also has some basic jQuery and NodeJS stuff), and then work through some of the various implementations of TodoMVC to see what tech speaks to me.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://todomvc.com/&#34;&gt;TodoMVC&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TodoMVC is a project that offers the same Todo application implemented using MV* concepts in most of the popular JavaScript MV* frameworks of today. These frameworks include Backbone, Ember, AngularJS, and Spine, to name a few. TodoMVC offers a great way to see how different stacks approach the same problem.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Other tools that are relevant to my cause and look promising include:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ace.ajax.org/&#34;&gt;Ace&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ace is a standalone code editor written in JavaScript. Our goal is to create a web-based code editor that matches and extends the features, usability, and performance of existing native editors such as TextMate, Vim, or Eclipse. It can be easily embedded in any web page and JavaScript application. Ace is developed as the primary editor for Cloud9 IDE and the successor of the Mozilla Skywriter (Bespin) Project.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;http://sharejs.org/&#34;&gt;ShareJS&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ShareJS is an Operational Transform library for NodeJS &amp;amp; browsers. It lets you easily do live concurrent editing in your app.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While I personally have a lot of Rails experience, I’m not going to shy away from NodeJS and other solutions. I almost welcome the opportunity to try something new these days. I’m also very excited to see that the &lt;a href=&#34;http://node.ph/&#34;&gt;NodePhilly&lt;/a&gt; group has gotten off the ground — I hope to make the next meeting in September.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>