<?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: Ryan Overton</title>
    <description>The latest articles on DEV Community by Ryan Overton (@onyxprime).</description>
    <link>https://dev.to/onyxprime</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%2F280237%2F684a3bfe-0481-411c-a994-e8b5ae6618a9.jpeg</url>
      <title>DEV Community: Ryan Overton</title>
      <link>https://dev.to/onyxprime</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/onyxprime"/>
    <language>en</language>
    <item>
      <title>Set up a Neon PR branch for a React Native Expo application using GitHub actions</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Mon, 18 Nov 2024 17:11:49 +0000</pubDate>
      <link>https://dev.to/hackmamba/set-up-a-neon-pr-branch-for-a-react-native-expo-application-using-github-actions-54n0</link>
      <guid>https://dev.to/hackmamba/set-up-a-neon-pr-branch-for-a-react-native-expo-application-using-github-actions-54n0</guid>
      <description>&lt;p&gt;It is essential to test any changes before merging them into a main or feature branch to catch bugs before they make it to production and ensure existing functionality continues to work as expected. Testing against a copy of production data is recommended to better find data-related issues.&lt;/p&gt;

&lt;p&gt;Previously, this process was problematic and time-consuming, often involving multiple teams. Luckily, Neon has a built-in &lt;a href="https://neon.tech/docs/introduction/branching" rel="noopener noreferrer"&gt;branching mechanism&lt;/a&gt;, which allows you to create a copy of your data quickly.&lt;/p&gt;

&lt;p&gt;In this tutorial, you will learn how to create a preview build for each pull request for a React Native Expo application. You will also learn how to set up a corresponding Neon database branch to be used with the preview build—and all this will be done within a single &lt;a href="https://docs.github.com/en/actions" rel="noopener noreferrer"&gt;GitHub Action&lt;/a&gt;. Then, once the pull request is closed, you’ll learn how to clean up your resources with another GitHub Action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we begin, you will need to have a few things already set up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;a href="https://expo.dev/signup" rel="noopener noreferrer"&gt;Expo account&lt;/a&gt; for deploying and testing preview branches&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://console.neon.tech/signup" rel="noopener noreferrer"&gt;Neon account&lt;/a&gt; with a database project for branching&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://docs.github.com/en/repositories/creating-and-managing-repositories/quickstart-for-repositories" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; containing your Expo application&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up GitHub
&lt;/h2&gt;

&lt;p&gt;The first thing we need to do is add the following secrets and variables to our GitHub repository. These secrets and variables will be used throughout our GitHub Actions.&lt;/p&gt;

&lt;p&gt;On your GitHub repository page, navigate to &lt;code&gt;Settings&lt;/code&gt; → &lt;code&gt;Secrets and variables&lt;/code&gt; → &lt;code&gt;Actions&lt;/code&gt; and add the following secrets and variables.&lt;/p&gt;

&lt;p&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%2Fdq6wvzyef4rgk02it3e3.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%2Fdq6wvzyef4rgk02it3e3.png" alt="Github settings showing the secrets tab on the secrets and variables page" width="800" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Neon API Key:&lt;/strong&gt;  Obtain a Neon API key from the &lt;code&gt;API Keys&lt;/code&gt;  by clicking on your avatar in the upper right corner of the Neon dashboard, then &lt;code&gt;Account Settings&lt;/code&gt; → &lt;code&gt;API Keys&lt;/code&gt;. Once you have created your API key, add it to your GitHub projects &lt;code&gt;Repository Secrets&lt;/code&gt; with the name &lt;code&gt;NEON_API_KEY&lt;/code&gt;.&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%2Foan9ups0cqqnc2vsv0eu.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%2Foan9ups0cqqnc2vsv0eu.png" alt="Neon account settings page showing the API keys tab" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Neon Project ID&lt;/strong&gt;: The Neon Project ID can be obtained from your Neon project’s &lt;code&gt;Settings&lt;/code&gt; → &lt;code&gt;General&lt;/code&gt; page. Add the Neon Project ID to your GitHub projects &lt;code&gt;Repository Variables&lt;/code&gt; under the name &lt;code&gt;NEON_PROJECT_ID&lt;/code&gt;.&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%2Fsxte12zv69gmq9r8f7r3.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%2Fsxte12zv69gmq9r8f7r3.png" alt="Neon dashboard showing where to get the project ID" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Neon Database Username:&lt;/strong&gt; Add the DB Role to be used for branch creation to your GitHub projects &lt;code&gt;Repository Variables&lt;/code&gt; under the name &lt;code&gt;NEON_USERNAME&lt;/code&gt;.&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%2Fp3l9xlenk1nai0xbb8mn.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%2Fp3l9xlenk1nai0xbb8mn.png" alt="Neon project dashboard highlighting where to set the DB role" width="800" height="539"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expo Token&lt;/strong&gt;: Obtain an Expo access token by going to &lt;code&gt;Account Settings&lt;/code&gt; → &lt;code&gt;Access tokens&lt;/code&gt; from the Expo dashboard. Then add a &lt;code&gt;Robot user&lt;/code&gt; by clicking on &lt;code&gt;Add robot&lt;/code&gt; and giving it the name &lt;code&gt;GITHUB_ACTIONS&lt;/code&gt;. Next, click &lt;code&gt;Create token&lt;/code&gt; and give it a descriptive, meaningful name, something like &lt;code&gt;GitHub actions token for PR builds&lt;/code&gt;. Finally, copy the token and add it to your GitHub projects &lt;code&gt;Repository Secrets&lt;/code&gt; with the name &lt;code&gt;EXPO_TOKEN&lt;/code&gt;.&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%2Fmuxeh9h26chefebzr13f.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%2Fmuxeh9h26chefebzr13f.png" alt="Expo account settings page showing where to obtain an Expo access token " width="800" height="537"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating a custom preview build for pull requests
&lt;/h2&gt;

&lt;p&gt;With the GitHub project secrets and variables set, it’s time to configure GitHub Actions to handle pull requests made to the repository.&lt;/p&gt;

&lt;p&gt;Create a new GitHub Actions file from your Expo project's root directory in the GitHub workflows directory.&lt;/p&gt;

&lt;p&gt;MacOS / Linux&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch ./.github/workflows/deploy-preview.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Windows&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir "./.github/workflows" &amp;amp;&amp;amp; call &amp;gt; ./.github/workflows/deploy-preview.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The following code defines the steps the GitHub Action will perform. Copy and paste this code into the file you created above.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Deploy Preview
run-name: Create a preview build 🚀

on: [pull_request]

env:
  NEON_API_KEY: ${{ secrets.NEON_API_KEY }}
  NEON_PROJECT_ID: ${{ vars.NEON_PROJECT_ID }}
  NEON_USERNAME: ${{ vars.NEON_USERNAME}}

jobs:
  deploy-preview:
    permissions: write-all
    runs-on: ubuntu-latest
    steps:
      - name: 🏗 Setup repo
        uses: actions/checkout@v4

      - name: 🚀 Create Neon Branch
        id: create-branch
        uses: neondatabase/create-branch-action@v5
        with:
          project_id: ${{ env.NEON_PROJECT_ID }}
          # parent: dev # optional (defaults to your primary branch)
          branch_name: preview/pr-${{ github.event.number }}-${{ github.event.pull_request.head.ref }}
          username: ${{ env.NEON_USERNAME }}
          database: dg_db # database to branch
          api_key: ${{ env.NEON_API_KEY }}

      - run: echo "EXPO_PUBLIC_NEON_URL=${{ steps.create-branch.outputs.db_url }}?sslmode=require" &amp;gt;&amp;gt; $GITHUB_ENV

      - name: 🏗 Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: 18.x
          cache: npm

      - name: 🏗 Setup Expo CLI
        uses: expo/expo-github-action@v8
        with:
          eas-version: latest
          token: ${{ secrets.EXPO_TOKEN }}

      - name: 📦 Install dependencies
        run: npm install

      - name: 🚀 Create Expo preview
        uses: expo/expo-github-action/preview@v8
        with:
          command: eas update --auto --branch ${{ github.event.pull_request.head.ref }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The first section defines the GitHub Actions name, the events it responds to (in this case, when a pull request is created), and the environment variables that will be used throughout the various GitHub Action steps.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Deploy Preview
run-name: Create a preview build 🚀

on: [pull_request]

env:
  NEON_API_KEY: ${{ secrets.NEON_API_KEY }}
  NEON_PROJECT_ID: ${{ vars.NEON_PROJECT_ID }}
  NEON_USERNAME: ${{ vars.NEON_USERNAME}}

jobs:
  deploy-preview:
    permissions: write-all
    runs-on: ubuntu-latest
    steps:
      - run: echo project_id ${{ env.NEON_PROJECT_ID}}

      - name: 🏗 Setup repo
        uses: actions/checkout@v4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The next section uses the &lt;code&gt;Create Branch Action&lt;/code&gt; step provided by Neon to create a branch from our primary branch, using a specific pattern to create a unique branch name for the Neon database. Using this unique and reproducible pattern ensures it can be automatically deleted once the pull request is closed.&lt;/p&gt;

&lt;p&gt;Once the branch is created, a new environment variable is created, &lt;code&gt;EXPO_PUBLIC_NEON_URL&lt;/code&gt;, with the newly created database URL. The environment variable should be the same one used within your Expo application to connect to your Neon database. If it is not, update the variable name used in the GitHub Action to match what is used in your application. &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: 🚀 Create Neon Branch
  id: create-branch
  uses: neondatabase/create-branch-action@v5
  with:
    project_id: ${{ env.NEON_PROJECT_ID }}
    # parent: dev # optional (defaults to your primary branch)
    branch_name: preview/pr-${{ github.event.number }}-${{ github.event.pull_request.head.ref }}
    username: ${{ env.NEON_USERNAME }}
    database: dg_db # database to branch
    api_key: ${{ env.NEON_API_KEY }}

- run: echo "EXPO_PUBLIC_NEON_URL=${{ steps.create-branch.outputs.db_url }}?sslmode=require" &amp;gt;&amp;gt; $GITHUB_ENV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Lastly, it configures the build environment for the Expo application, creates a preview build, publishes it to the Expo cloud for testing, and adds a comment to the pull request. &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: 🏗 Setup Node
  uses: actions/setup-node@v3
  with:
    node-version: 18.x
    cache: npm

- name: 🏗 Setup Expo CLI
  uses: expo/expo-github-action@v8
  with:
    eas-version: latest
    token: ${{ secrets.EXPO_TOKEN }}

- name: 📦 Install dependencies
  run: npm install

- name: 🚀 Create Expo preview
  uses: expo/expo-github-action/preview@v8
  with:
    command: eas update --auto --branch ${{ github.event.pull_request.head.ref }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The pull request comment added to the pull request is done as part of the &lt;code&gt;Create Expo preview&lt;/code&gt; step. It contains information about the published app, such as the project name and platforms it was published to, as well as a QR code to open the preview build within the Expo Go app on your corresponding mobile device.&lt;/p&gt;

&lt;p&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%2Fc2rmv49nnxx4ok63n0zj.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%2Fc2rmv49nnxx4ok63n0zj.png" alt="Comment left by the GitHub action showing a QR code to the Expo preview build" width="659" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’re now free to perform any actions on your preview app that would add, update, or modify data without fear of impacting or polluting data or resources in your production environment with test data. &lt;/p&gt;
&lt;h2&gt;
  
  
  Cleaning up the preview environment
&lt;/h2&gt;

&lt;p&gt;Once the pull request has been merged, or closed, it is recommended to clean up the resources no longer needed, like the Neon database branch created when the pull request was made. &lt;/p&gt;

&lt;p&gt;From the root directory of your Expo project, create a new GitHub Actions file in the GitHub workflows directory.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch .github/workflows/cleanup-preview.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The following code defines the steps the GitHub Action will perform. Copy and paste this code into the file you created above.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Clean up Preview Deployment
on:
  pull_request:
    types: [closed]
env:
  NEON_API_KEY: ${{ secrets.NEON_API_KEY }}
  NEON_PROJECT_ID: ${{ vars.NEON_PROJECT_ID }}

jobs:
  delete-preview:
    runs-on: ubuntu-latest
    steps:
      - name: Delete Neon Branch
        uses: neondatabase/delete-branch-action@v3.1.5
        with:
          project_id: ${{ vars.NEON_PROJECT_ID }}
          branch: preview/pr-${{ github.event.number }}-${{ github.event.pull_request.head.ref }}
          api_key: ${{ secrets.NEON_API_KEY }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The first section again defines the GitHub Actions name, the events it responds to (in this case, when a pull request is closed), and the environment variables that will be used throughout the various GitHub Action steps.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Clean up Preview Deployment
on:
  pull_request:
    types: [closed]

env:
  NEON_API_KEY: ${{ secrets.NEON_API_KEY }}
  NEON_PROJECT_ID: ${{ vars.NEON_PROJECT_ID }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The last section deletes the Neon database branch created when the pull request was made using the same branch naming pattern when the pull request was made.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  delete-preview:
    runs-on: ubuntu-latest
    steps:
      - name: Delete Neon Branch
        uses: neondatabase/delete-branch-action@v3.1.5
        with:
          project_id: ${{ env.NEON_PROJECT_ID }}
          branch: preview/pr-${{ github.event.number }}-${{ github.event.pull_request.head.ref }}
          api_key: ${{ env.NEON_API_KEY }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;And that’s all there is to it! When a pull request is merged or closed, its corresponding Neon database branch is deleted. &lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/0c1c683f9ad340958d5e6c7adc115b37"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this tutorial, you learned how to create a preview build of a React Native Expo application for each pull request made. You also learned how to create a corresponding Neon database branch for each preview build, passing its connection string along to the Expo application build process.&lt;/p&gt;

&lt;p&gt;If you want to test this yourself, use the sample code and instructions on &lt;a href="https://github.com/OnyxPrime/expo-neon-preview-build" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using Custom Fonts on your Website</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Mon, 14 Feb 2022 22:07:25 +0000</pubDate>
      <link>https://dev.to/onyxprime/using-custom-fonts-on-your-website-3g15</link>
      <guid>https://dev.to/onyxprime/using-custom-fonts-on-your-website-3g15</guid>
      <description>&lt;p&gt;The team at Google has provided an amazing library of fonts which you can use for free on your website. These fonts have allowed developers to show their creativity, as well as uniqueness. In addition, Google has also provided a service allowing you to load any of these fonts into your site without having to host them yourself. Which quite a few of us are probably using at this very moment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Robot"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;But what about when you’ve got a custom font that’s been created just for you, or you can't use the service provided by Google for business or other reasons? How can you use that font on your site?&lt;/p&gt;

&lt;p&gt;In this article, I’ll show you how you can use those custom fonts, or still use the fonts provided by Google without using the Google Fonts APIs. &lt;/p&gt;
&lt;h2&gt;
  
  
  Font types
&lt;/h2&gt;

&lt;p&gt;There are several different font types and not all browser versions support every font type. So, check the table below to understand what browsers support what types and the versions at which they started supporting them.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Font format&lt;/th&gt;
&lt;th&gt;IE&lt;/th&gt;
&lt;th&gt;Chrome&lt;/th&gt;
&lt;th&gt;Firefox&lt;/th&gt;
&lt;th&gt;Safari&lt;/th&gt;
&lt;th&gt;Opera&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TTF/OTF&lt;/td&gt;
&lt;td&gt;9.0*&lt;/td&gt;
&lt;td&gt;4.0&lt;/td&gt;
&lt;td&gt;3.5&lt;/td&gt;
&lt;td&gt;3.1&lt;/td&gt;
&lt;td&gt;10.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WOFF&lt;/td&gt;
&lt;td&gt;9.0&lt;/td&gt;
&lt;td&gt;5.0&lt;/td&gt;
&lt;td&gt;3.6&lt;/td&gt;
&lt;td&gt;5.1&lt;/td&gt;
&lt;td&gt;11.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WOFF2&lt;/td&gt;
&lt;td&gt;14.0&lt;/td&gt;
&lt;td&gt;36.0&lt;/td&gt;
&lt;td&gt;39.0&lt;/td&gt;
&lt;td&gt;10.0&lt;/td&gt;
&lt;td&gt;26.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SVG&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;3.2&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EOT&lt;/td&gt;
&lt;td&gt;6.0&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;* table data provided by &lt;a href="https://www.w3schools.com/css/css3_fonts.asp"&gt;w3schools&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It's worth noting, the &lt;a href="https://www.w3.org/"&gt;World Wide Web Consortium (W3C)&lt;/a&gt; recommends using the Web Open Font Format (WOFF). WOFF is a TrueType font (TTF) or OpenType font (OTF) with compression. WOFF 2.0 is a newer version of WOFF, just with better compression. &lt;/p&gt;
&lt;h2&gt;
  
  
  Download font
&lt;/h2&gt;

&lt;p&gt;To get your font from Google, navigate to &lt;a href="https://fonts.google.com"&gt;https://fonts.google.com&lt;/a&gt;, select your desired font, and click &lt;code&gt;Download family&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyghrw2x4il9qqn8mbsu0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyghrw2x4il9qqn8mbsu0.png" alt="Screenshot of Google Fonts website displaying Supermercado One font" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This downloads a ZIP file containing all the variations (medium, bold, italic, etc.) of the font. Once you unzip the file, you will notice it downloads a TTF format. You can either use this as is, or convert it to WOFF2. Converting is recommended for production.&lt;/p&gt;
&lt;h2&gt;
  
  
  Convert font
&lt;/h2&gt;

&lt;p&gt;To convert the font to WOFF2, you can use a service like &lt;a href="https://cloudconvert.com/ttf-to-woff2"&gt;cloudconvert&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6778o8hyfu4k5za7if0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6778o8hyfu4k5za7if0.png" alt="Screenshot of cloudconvert website" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upload your TTF file, click &lt;code&gt;Convert&lt;/code&gt;, then click &lt;code&gt;Download&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Use font in your website
&lt;/h2&gt;

&lt;p&gt;With your font converted to WOFF2, you’re ready to add it to your website.&lt;/p&gt;

&lt;p&gt;Move the converted font into your website folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgyptc1el6cafm60vb4hw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgyptc1el6cafm60vb4hw.png" alt="File explorer in VS Code showing addition of new font" width="800" height="669"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you’ll add a &lt;code&gt;@font-face&lt;/code&gt; rule. The &lt;code&gt;@font-face&lt;/code&gt; rule allows you to define new font types which can be used throughout your CSS. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;@font-face&lt;/code&gt; rule requires you to give the font a name and the url where the font file is located. When the rule is loaded into the client's browser, it will download and load the font file from the specified location. &lt;/p&gt;

&lt;p&gt;Place the &lt;code&gt;@font-face&lt;/code&gt; rule at the top of your &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; tag or CSS.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@font-face {
  font-family: mySuperFont;
  src: url(assets/SupermercadoOne-Regular.woff2);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, the font can be referenced by the other styles in CSS,&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;p {
  font-family: mySuperFont;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;or by inline styling&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div style='font-family:mySuperFont'&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0hvldxayswkybh2psanx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0hvldxayswkybh2psanx.png" alt="Screenshot of sample app showing 2 lines using a custom font and another using the default style" width="800" height="680"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Sample app
&lt;/h2&gt;

&lt;p&gt;I've created a working sample application demonstrating how this concept and placed the code for it on &lt;a href="https://github.com/OnyxPrime/custom_fonts_sample"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/OnyxPrime"&gt;
        OnyxPrime
      &lt;/a&gt; / &lt;a href="https://github.com/OnyxPrime/custom_fonts_sample"&gt;
        custom_fonts_sample
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Using custom fonts in your website
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;If you've got any questions, comments, or other ways you get custom fonts in your websites let me know in the comments below.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>css</category>
      <category>html</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>4 Ways to Optimize 3rd Party Libraries</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Thu, 07 Oct 2021 18:11:50 +0000</pubDate>
      <link>https://dev.to/onyxprime/4-ways-to-optimize-3rd-party-libraries-5493</link>
      <guid>https://dev.to/onyxprime/4-ways-to-optimize-3rd-party-libraries-5493</guid>
      <description>&lt;p&gt;Web performance is an often overlooked metric of a company's website. It’s pushed to the back of the queue in preference of a site's look, layout and theme. While these areas of a site are important aspects of your visitors' experience, a poor loading and performing website will cause them to leave your site before it’s loaded. This means all the time and effort spent on crafting a great and compelling user experience was for naught.&lt;/p&gt;

&lt;p&gt;According to a &lt;a href="https://www.thinkwithgoogle.com/marketing-strategies/app-and-mobile/page-load-time-statistics/"&gt;study conducted by Google in 2017&lt;/a&gt;, as page load time goes from 1 second to 3 seconds the probability of a user navigating away increases 32%. The performance of your site ensures visitors get to go through the finely crafted experience teams have spent many hours creating.&lt;/p&gt;

&lt;p&gt;If you’re a 3rd party SaaS provider, performance is more important. Businesses want to use your service, but if it’s the cause of performance issues on their site, they will be looking to replace your service as soon as they can. &lt;/p&gt;

&lt;p&gt;At &lt;a href="https://www.ketch.com/"&gt;Ketch&lt;/a&gt;, one of our top priorities is to ensure our libraries are as optimized as they can be for performance. &lt;/p&gt;

&lt;p&gt;Here are 4 ways we use, and so can you, to optimize our libraries to ensure they don’t hinder the loading and performance of our customers' websites and applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use async/defer
&lt;/h2&gt;

&lt;p&gt;If at all possible you should design your library to be loaded asynchronously, rather than synchronously. This is to allow page rendering to occur while the library is being downloaded, unlike synchronous scripts which stop page rendering until the script is downloaded, parsed, and executed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8fl1dz6i02a7hddmuwo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8fl1dz6i02a7hddmuwo.png" alt="Synchronous loading of javascript" width="800" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can utilize the &lt;code&gt;async&lt;/code&gt; or &lt;code&gt;defer&lt;/code&gt; attributes to instruct the browser to continue parsing the HTML while the scripts are downloaded.&lt;/p&gt;

&lt;p&gt;While both the &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;defer&lt;/code&gt; attributes tell the browser to download while the page is being rendered, the point at which the downloaded script is executed is where they differ.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;async&lt;/code&gt; attribute tells the browser to execute the script the first chance it gets after it has been downloaded, but before the &lt;code&gt;load&lt;/code&gt; event is fired.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7mdnl4f73r2uchlstj1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7mdnl4f73r2uchlstj1.png" alt="Asynchronous loading of javascript" width="800" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The ‘defer’ attribute tells the browser to execute the script after the HTML has finished parsing, but before the &lt;code&gt;DOMContentLoaded&lt;/code&gt; event is fired.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8csnu9fuaf39psshjkve.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8csnu9fuaf39psshjkve.png" alt="Defer loading of javascript" width="800" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Remove unused code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F002vitg0g3hsvhfdvzzh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F002vitg0g3hsvhfdvzzh.png" alt="Room with many stacked arm chairs on one side" width="640" height="427"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@v2osk?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;v2osk&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/remove-unused?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyTex"&gt;Unsplash&lt;/a&gt;   &lt;/p&gt;

&lt;p&gt;To optimize the loading of your library you will probably run it through a bundling process to reduce the number of round trips to the server. Bundling combines your code files and their dependencies into a single file. &lt;/p&gt;

&lt;p&gt;What we tend to forget is that we rarely use all of the functions available within our dependencies, which come along for the ride during the bundling process. This can lead to an unnecessarily large file to download. &lt;/p&gt;

&lt;p&gt;To reduce this file size, implement a &lt;a href="https://webpack.js.org/guides/tree-shaking/"&gt;tree shaking&lt;/a&gt; process to remove all the code not being used.&lt;/p&gt;

&lt;p&gt;Tree shaking looks at the bundled file and attempts to determine which code paths are not called and remove them from the final output.&lt;/p&gt;

&lt;p&gt;Note: Tree shaking can have unintended side effects if it is too aggressive in removing what it thinks is unused code. This can cause unintended side-effects or broken logic on your page. You need to thoroughly test your page with the tree shaken file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Break larger JavaScript files into multiple, smaller logical files
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblyrx9h67z0y21iz34nk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblyrx9h67z0y21iz34nk.jpg" alt="Lego Star Wars Stormtrooper being pulled apart by Darth Vader" width="800" height="534"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@danielkcheung?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Daniel Cheung&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/construct-lego?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Above we talked about the bundling process, which combines your code and its dependencies into a single file to reduce the need for multiples to the server. Sometimes we don’t need all the functionality immediately upon page load. &lt;/p&gt;

&lt;p&gt;For instance, there may be function calls that require a user to press a button before it’s activated. This code can be separated into another file to be downloaded, or deferred, after the page’s HTML has been parsed. &lt;/p&gt;

&lt;h2&gt;
  
  
  Use a Content Delivery Network
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fregx6cddbn4rjx3por07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fregx6cddbn4rjx3por07.png" alt="World globe with several destinations marked" width="640" height="640"&gt;&lt;/a&gt;&lt;a href="https://storyset.com/people"&gt;People illustrations by Storyset&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With all the previous optimizations implemented, you may think you’ve done all you can to increase your page’s performance, but visitors to your customers site are not created equal, at least in the case of location.&lt;/p&gt;

&lt;p&gt;The further the visitor is away from your web server's physical location, and the speed of the network they’re connected to, affect how long it will take for their device to download your library.&lt;/p&gt;

&lt;p&gt;While the previous optimizations will help tremendously with how long a library takes to download, this will move the files closer to the visitor. This can be accomplished by utilizing a content delivery network (CDN), like &lt;a href="https://www.fastly.com/"&gt;Fastly&lt;/a&gt;, &lt;a href="https://www.akamai.com/us/en/cdn/"&gt;Akamai&lt;/a&gt;, or &lt;a href="https://www.cloudflare.com/cdn/"&gt;Cloudflare&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The CDN does not replace the need for a web server, but allows caching of a site’s content at strategic locations around the world. This caching closes the distance between your library and the visitor viewing your customers page, decreasing the download time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As a library creator, your responsibility doesn’t stop at getting the code working as expected. How it loads and affects the page on which it's executed is just as important. &lt;/p&gt;

&lt;p&gt;At Ketch we are continually monitoring and improving the performance of our libraries utilizing the tips above, ensuring we are never a hindrance to a customer’s site. &lt;/p&gt;

&lt;p&gt;Optimizing your library will show customers you care just as much about their site’s performance as they do.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>performance</category>
    </item>
    <item>
      <title>Weekly Win (47/2020)</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Tue, 17 Nov 2020 18:31:20 +0000</pubDate>
      <link>https://dev.to/kontent_ai/weekly-win-47-2020-4igb</link>
      <guid>https://dev.to/kontent_ai/weekly-win-47-2020-4igb</guid>
      <description>&lt;p&gt;When implementing a third-party library, we set expectations on how we believe it will be implemented, and when these expectations aren't met, we can get very frustrated and start taking it out on the team, or developer, who created the library. We also set these same expectations on other tasks we perform, and can be met with the same level of frustration and disappointment when things don't go as planned.&lt;/p&gt;

&lt;p&gt;A few weeks ago, I had the task of changing the water filter in our rent house refrigerator. It's used to filter water used in automatic icemakers and water dispensers built inside of refrigerators. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcaftkpllh4ytwwx5lmp8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcaftkpllh4ytwwx5lmp8.png" alt="refrigerator with water dispenser" width="551" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I set my expectations on how the water filter should be changed based on my past experience changing water filters over the past twelve plus years of home ownership. &lt;/p&gt;

&lt;p&gt;Here were the steps I followed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Buy new filter&lt;/li&gt;
&lt;li&gt;Remove old filter&lt;/li&gt;
&lt;li&gt;Insert new filter&lt;/li&gt;
&lt;li&gt;Enjoy clean water and ice&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process had worked well, without issue, until a few weeks ago. We recently moved in to a rent home and it was time to change the water filter. I followed my normal steps, but when I got to step two, something different happened. As I began removing the water filter, water started spraying all over the inside of the refrigerator. 😲 I tried just putting the old filter back on, but it didn't stop the spraying. At this point, I realized I needed to shutoff the water going to the refrigerator, conveniently located behind it.&lt;/p&gt;

&lt;p&gt;With the water shut off, inside of the refrigerator thoroughly soaked and water draining out on to the kitchen floor, I had two ways to handle the situation: let my frustration and anger at the implementation ruin the rest of my day, or flip my perspective and look at it in all it's hilarity, like my family was doing 😂.&lt;/p&gt;

&lt;p&gt;I took the second option and joined in on the laughing. I also looked as it as an opportunity to do something I probably wouldn't have done, clean out the refrigerator 😁 and add a new step to my process: turn off the water.&lt;/p&gt;

&lt;p&gt;So, the next time your faced with a failed set of expectations, instead of denigrating the team, or person, who missed those expectations, flip it around and look a it as an opportunity to change something for the better, even if it might be a little more work than we had thought, or hoped. After all, as developers, we should always be looking at ways to better improve our solutions, and practices, at least that's how I look at it.&lt;/p&gt;

&lt;p&gt;When's the last time you had your expectations not met and how'd you deal with it? &lt;/p&gt;

&lt;p&gt;I look forward to reading your responses below!🙂&lt;/p&gt;

</description>
      <category>win</category>
      <category>fail</category>
      <category>thirdparty</category>
      <category>development</category>
    </item>
    <item>
      <title>ASP.NET: The Next Generation</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Mon, 16 Nov 2020 20:58:38 +0000</pubDate>
      <link>https://dev.to/onyxprime/asp-net-the-next-generation-ofp</link>
      <guid>https://dev.to/onyxprime/asp-net-the-next-generation-ofp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Unless you've been locked away in a dark room for the past six years, you've likely already heard about ASP.NET Core. It is the reimagination of ASP.NET, the web framework we've grown to love, and at times hate 😜, over the past 18 years. With the former framework still being supported and actively worked on, it can be hard to make a case for switching off a framework with such a rich history, like ASP.NET, to a relatively new framework, even if it shares the same name.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, we're going to look at the reasons why the team building the next generation digital experience platform, Kentico Xperience, decided to transition to ASP.NET Core.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Friendly
&lt;/h2&gt;

&lt;p&gt;Let me start by saying, ASP.NET and the .NET Framework are not going anywhere anytime soon. Much of Windows still relies on the .NET Framework and until such time that it doesn't, there will still be support and bug fixes for the .NET Framework. But, and it is a big one, there will be no major updates to the .NET Framework beyond version 4.8.&lt;/p&gt;

&lt;p&gt;The future of .NET, and by virtue ASP.NET, is .NET Core. This is where investments are being placed. Which means you'll be able to take advantage of all the improvements being made to the platform and the languages used for development.&lt;/p&gt;

&lt;p&gt;As an example, many of the &lt;a href="https://devblogs.microsoft.com/dotnet/building-c-8-0/#platform-dependencies"&gt;C# 8.0 features have platform dependencies&lt;/a&gt; which are implemented in .NET Standard 2.1, which .NET Core 3.0 and newer will support, but &lt;a href="https://devblogs.microsoft.com/dotnet/building-c-8-0/#platform-dependencies"&gt;.NET Framework 4.8 never will&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, in order to stay innovative, competitive, and continue to attract top talent, the team looked for a platform that was familiar and would be supported for the foreseeable future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cross-platform Support
&lt;/h2&gt;

&lt;p&gt;Long gone are the days where clients will meet you where you are. As software creators, we NEED to be meeting our clients where they are and it's no longer exclusively on a dedicated platform, like Windows.&lt;/p&gt;

&lt;p&gt;Unlike its predecessor, ASP.NET Core does not require IIS or Windows to develop or run. This means you can use other operating systems, like macOS and Linux, to develop applications and as hosting environments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ijhy0mjcxunqcj0xhg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ijhy0mjcxunqcj0xhg1.png" alt=".NET Core cross-platform diagram" width="673" height="757"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This may not seem like a huge deal to some, but if you're looking at the cost to run a Windows environment versus a Linux environment, you'll likely start to see a growing difference in cost. This could end up greatly reducing the operating costs of your applications allowing you to adapt quickly to changes happening within your market. &lt;/p&gt;

&lt;p&gt;For development teams, this means we're able to reuse a majority of our code as we expand the reach of our application to other platforms.   &lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;Eight seconds. &lt;/p&gt;

&lt;p&gt;No, we're not talking about the movie chronicling the life of PRCA Bull Riding World Champion, Lane Frost, but the average attention span of a website visitor. And if your site takes longer than three seconds to load, there's &lt;a href="https://www.towermarketing.net/blog/winning-the-fight-against-a-website-users-attention-span/"&gt;a 40% chance they'll abandon their visit&lt;/a&gt; to your website. So, it's no wonder most clients, partners and users will tell you your site needs to be faster.&lt;/p&gt;

&lt;p&gt;This is one of the biggest benefits you'll gain when you switch to using ASP.NET Core and in my opinion, one of the most compelling reasons to make the move to ASP.NET Core.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.techempower.com/benchmarks/#section=data-r19&amp;amp;hw=ph&amp;amp;test=composite"&gt;Benchmark data&lt;/a&gt; shows ASP.NET core can do approximately 285,000 requests per second, whereas, ASP.NET averages approximately 1500 requests per second.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.techempower.com/benchmarks/#section=data-r19&amp;amp;hw=ph&amp;amp;test=composite"&gt;Benchmark data&lt;/a&gt; shows ASP.NET core can do approximately 285,000 requests per second, where as, ASP.NET  averages approximately 1500 requests per second.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe7eegwnktlhjkwtkhfkv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe7eegwnktlhjkwtkhfkv.png" alt="Benchmark test results" width="800" height="97"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;After moving to ASP.NET Core, the Kentico Xperience team ran some preliminary tests on startup times. They found the Dancing Goat starter site was starting up 4 times faster using ASP.NET Core.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Filx7herytwp4wrgg4yj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Filx7herytwp4wrgg4yj4.png" alt="Dancing Goat site startup times" width="800" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Although migrating to a new platform is never fun and almost never easy, the .NET Core teams continue to add APIs and features to help ease migration efforts from the .NET Framework. The Kentico Xperience team also understands this and is currently looking at options to aid clients and partners in their migration efforts.&lt;/p&gt;

&lt;p&gt;The Kentico Xperience team found being future friendly, cross-compatible and highly performant compelling reasons to move from ASP.NET to ASP.NET Core. &lt;/p&gt;

&lt;p&gt;What do you think? Are you ready to take the plunge? Something holding you back?&lt;/p&gt;

&lt;p&gt;Need a little more convincing? Download &lt;a href="https://xperience.io/cmsctx/pv/60ad2c50-edc5-46e9-bb28-84bb78f14716/culture/en-US/wg/76d1e68f-ac8a-4011-b409-8a0cb0087da9/readonly/0/pts/637411672826254783/ea/1/h/626941afb2eb1a5ecb5d346e1e35425aa565c1e354fc6d4298ec36e89ef2dd16/-/specials/kx13-trial?uh=186ffaede153c28428f4eb805dac1abb2d3e522de85b3bc58497bd3c31d7f3ed"&gt;Xperience 13&lt;/a&gt; and see the impact of our transition to ASP.NET Core.&lt;/p&gt;

</description>
      <category>aspnetcore</category>
      <category>cms</category>
      <category>dxp</category>
      <category>kenticoxperience</category>
    </item>
    <item>
      <title>🤦‍♂️ Weekly fail (41/2020)</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Tue, 06 Oct 2020 13:20:15 +0000</pubDate>
      <link>https://dev.to/kontent_ai/weekly-fail-41-2020-4l5d</link>
      <guid>https://dev.to/kontent_ai/weekly-fail-41-2020-4l5d</guid>
      <description>&lt;p&gt;Last week, I spent the better part of &lt;a href="https://twitch.tv/developersgarage"&gt;my Friday livestream&lt;/a&gt; working on solving a single problem. With a little more attention to detail, this wouldn't have been a problem at all.&lt;/p&gt;

&lt;p&gt;I had just gotten done implementing a custom 404 handler for a static site I have been developing for a friend. I went to test the handler, but it wasn't working. I was still getting the generic 404 exception, &lt;code&gt;cannot GET \page&lt;/code&gt;, when a page does not exist. I spent the next 1.5 - 2 hours trying to solve why the redirect wasn't working and just before I ended my stream, I figured it out.&lt;/p&gt;

&lt;p&gt;I had been working on this site many times over the course of several weeks and I typically leave my working pages open in a browser window, including the site running on localhost, specifically localhost:8080. I also leave my command windows open because that's where the static site generator CLI is running and watches for changes in order to rebuild and reload the site.&lt;/p&gt;

&lt;p&gt;At some point, the command window, or CLI, crashed and when it did it left a Node.js process running in the background. This process was still running and using localhost:8080 to serve up my site. On Friday, when I reran the CLI in a command window, it started up another Node.js process, this time serving it up on localhost:8081. 🤦‍♂️ And did I mention, the CLI tells you specifically where it is serving your site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F79ojy2d93s1givhfqe6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F79ojy2d93s1givhfqe6t.png" alt="Access URLs from BrowserSync" width="370" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lesson learned:&lt;/em&gt; &lt;strong&gt;Pay attention to what the CLI is outputting and when in doubt, restart everything, including your computer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I love the opportunity to post my fails in hopes of saving someone from the same fate, but also to show no matter how many years of experience you have, we all still struggle, and fail, from time to time. So don't get all down on yourself when it happens to you 😉. &lt;/p&gt;

&lt;p&gt;What was one of your fails last week?&lt;/p&gt;

&lt;p&gt;Also, if you ever want to chat about it, or anything for that matter, drop in to &lt;a href="https://twitch.tv/developersgarage"&gt;my stream&lt;/a&gt; where you'll find an amazing, supportive group ready to welcome you and share their wins and fails!&lt;/p&gt;

</description>
      <category>fail</category>
      <category>lessonlearned</category>
      <category>node</category>
      <category>jamstack</category>
    </item>
    <item>
      <title>🤦‍♂️ Weekly fail (36/2020)</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Tue, 01 Sep 2020 13:54:18 +0000</pubDate>
      <link>https://dev.to/kontent_ai/weekly-fail-36-2020-b41</link>
      <guid>https://dev.to/kontent_ai/weekly-fail-36-2020-b41</guid>
      <description>&lt;p&gt;If there's one thing I've learned in my 13 years of being a software developer, it's that nothing is easy! Even the tasks that seem the most trivial. &lt;/p&gt;

&lt;p&gt;A little over a year ago, I was given the amazing opportunity to become a developer evangelist for one of the leading content management providers out there, &lt;a href="https://kentico.com"&gt;Kentico&lt;/a&gt;. One of the things I love most about being a developer evangelist, and the primary reason I changed roles, is I get to create content about my passion, software development. &lt;/p&gt;

&lt;p&gt;One of the mediums for my content is video uploaded to my &lt;a href="https://rebrand.ly/developersgarage"&gt;YouTube channel&lt;/a&gt;. You would think sitting down in front of a camera, recording yourself talking would be a no brainer. Well remember in the beginning I said "nothing is easy"... yeah, that includes sitting down in front of camera and recording yourself talking. &lt;/p&gt;

&lt;p&gt;In my latest &lt;a href="https://www.youtube.com/watch?v=4TIDvb-Xo08"&gt;video&lt;/a&gt;, I recorded a 20 minute portion without audio 🤦‍♂️. At some point I muted the microphone because it was providing background noise as I was trying to edit a video. To make matters worse, I didn't actually find this out until I started to editing this video. Needless to say I had to go back and re-record that section.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lesson learned:&lt;/em&gt; &lt;strong&gt;No matter how many times you've done it, ALWAYS perform a video and audio test before you begin your production recording! That's right, testing isn't just for software development anymore. 😜&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Bonus&lt;/em&gt;: &lt;strong&gt;Own your fails and be proud of them! Your failures and how you handle them, say so much more about you, than your successes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What's been one of your latest fails?&lt;/p&gt;

</description>
      <category>fail</category>
      <category>lessonlearned</category>
      <category>youtube</category>
      <category>recording</category>
    </item>
    <item>
      <title>My Twilio Hackathon Successful Failure</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Sun, 03 May 2020 19:56:30 +0000</pubDate>
      <link>https://dev.to/onyxprime/my-twilio-hackathon-successful-failure-2dk4</link>
      <guid>https://dev.to/onyxprime/my-twilio-hackathon-successful-failure-2dk4</guid>
      <description>&lt;p&gt;This past April, I had the opportunity to participate in the Twilio x DEV community hackathon. Participants had the entire month of April to develop and submit your project. &lt;/p&gt;

&lt;p&gt;It's only the 3rd hackathon in which I've participated and my first, hopefully of many, virtual hackathons. Unfortunately, due to some unforeseen, non-project related, circumstances, I was unable to submit my project on time. 😢 This is the failure I'm speaking of in the title.&lt;/p&gt;

&lt;p&gt;Wait, but you called it a "successful" failure. How can a failure be a success? Some of you may already understand what I mean by this, but for those who don't, please bear with me. Everything will become clear by the end. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Project
&lt;/h2&gt;

&lt;p&gt;I struggled a little with what should the project be, but with the help of a friend, &lt;a href="https://dev.to/ondrabus"&gt;Ondrej Polesny&lt;/a&gt;, the ifBored project was born. &lt;/p&gt;

&lt;p&gt;Throughout a person's life, there are times where one has nothing to do. Let's be honest though, there's always something to do. We just need a little help deciding what we should do 😉. That's where my project comes in.&lt;/p&gt;

&lt;p&gt;When you are not sure what you should do next, text a number, visit a site on your phone, tablet, or computer, answer a few questions, and get a suggestion about what you should do next. Sounds simple, right!?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxk9sa0izyh033d6fxfvk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxk9sa0izyh033d6fxfvk.png" alt="High level diagram of the ifBored project" width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Technology
&lt;/h2&gt;

&lt;p&gt;I've spent most of my 13 professional years in software development working within the Microsoft stack, specifically using C# and Azure. &lt;/p&gt;

&lt;p&gt;I took the hackathon as an opportunity to step outside my comfort zone and work with some technologies and platforms I had very little experience with and had not worked with previously. This, by far, was the most challenging piece of the project.&lt;/p&gt;

&lt;p&gt;Oh, and I also did the majority of it LIVE on my Twitch channel &lt;a href="https://twitch.tv/developersgarage"&gt;Developers Garage&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;I chose JavaScript because it's one of the top programming languages and one which I'm not as familiar with as I'd like to be. To me, JavaScript is like the wild west 🤠. The rules, if any, aren't clear and you don't find out about them, until after you've tried it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/JU4dLmUzKWgZgr2VkY/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/JU4dLmUzKWgZgr2VkY/giphy.gif" alt="Cowboys riding and shooting guns animated GIF" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also chose to use a serverless infrastructure, so I didn't have to setup, configure and manage a server environment. Plus, there are some great free options for serverless environments, which plays well with proof of concepts and hackathons. That's where Netlify comes in. &lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt; is an all-in-one platform to build, test and deploy your modern web applications.&lt;/p&gt;

&lt;p&gt;For user interaction, I went with Twilio because it was part of the requirement and they're an amazing communications platform across the board. They also provide great documentation and software development kits (SDKs) for use with whatever framework you're working with. &lt;/p&gt;

&lt;p&gt;To store the questions and suggestions, I could have used text files with JSON in them, but I wanted to use a service which abstracted away the management and distribution of this data, as well as, provide a great experience. That is why I chose &lt;a href="https://rebrand.ly/dgakontent"&gt;Kentico Kontent&lt;/a&gt;, a content as a service platform providing all the benefits of a headless service platform.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Full disclosure: I currently work as a developer evangelist for Kentico Kontent 😊&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When questions are asked and answers provided, we need to store this conversation. For conversation storage, I chose to use &lt;a href="https://fauna.com/"&gt;Fauna&lt;/a&gt;, a serverless, No SQL database featuring native GraphQL. The structureless nature of a No SQL database is very appealing to me because it allows the data structure to naturally evolve with the application.&lt;/p&gt;

&lt;p&gt;In case you haven't realized it yet, there is a general theme in my choices of platforms and services, I'm using for the project. They all have a FREE tier meaning anyone can try, improve and contribute to this project without fear of having to spend any money.&lt;/p&gt;

&lt;p&gt;For phase 1 of the project, a user texts our Twilio number, which calls the associated endpoint, a serverless function hosted on Netlify, which retrieves the conversation from Fauna, gets the first question and returns it to Twilio, which responds back to the user with the question. This same process continues, except stores the answers to the questions in the conversation in Fauna, until all questions have been answered. Once all questions have been answered, the system will suggest something to learn, or do, and provide a resource. &lt;/p&gt;

&lt;p&gt;Phase 1 works functionally, but is missing the decision making logic. So, it currently asks a few questions and returns the only suggestion it know.&lt;/p&gt;

&lt;p&gt;For future phases, we will implement other platforms (web, voice, WhatsApp, etc.) to allow different users to interact with the service, as well as, implement the decision making logic 😜 and add the ability to submit new suggestions through a web interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So, back to why I called this project a "successful failure". I learned SO much while working on this project and feel so good about the work accomplished. While I would have liked to have submitted my project into the hackathon, the ultimate goal was to learn something new and that is exactly what I did. This is why I called this project a "success".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/XreQmk7ETCak0/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/XreQmk7ETCak0/giphy.gif" alt="Boy giving thumbs up" width="320" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am much better, and more comfortable, with JavaScript and am more familiar with Netlify and how to host various services and applications on it. I am more comfortable using a NoSql database and how they're constructed. I also realize there is SO much more to learn and am excited to continue this project.&lt;/p&gt;

&lt;p&gt;That's right, this project is far from done! It will continue to be done in the open and LIVE on my Twitch channel &lt;a href="https://twitch.tv/developersgarage"&gt;Developers Garage&lt;/a&gt;. The latest schedule for my streams are found on the channel, but be sure to like the channel by clicking the ♥ and turning on notifications to be notified the next time I go live.  Also, follow me on &lt;a href="https://twitter.com/ryano9791"&gt;Twitter&lt;/a&gt; where I also post when I go live.&lt;/p&gt;

&lt;p&gt;I can't do this alone, nor do I want to. This project wouldn't be where it is, if it wasn't for others in the development community. Thank you to those who joined the previous streams!&lt;/p&gt;

&lt;p&gt;You too can help make this project a reality and resource for those who have down time and need something to do. To help, fork the &lt;a href="https://github.com/devsgarage/ifbored"&gt;repo&lt;/a&gt;, join the &lt;a href="https://twitch.tv/developersgarage"&gt;live stream sessions&lt;/a&gt; or comment and create issues. &lt;/p&gt;

&lt;p&gt;If you're looking to learn more about the technology used, join me on the &lt;a href="https://twitch.tv/developersgarage"&gt;Developers Garage live stream&lt;/a&gt; where it's always an ask me anything stream.&lt;/p&gt;

&lt;p&gt;See you in the chat!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb23aw0jfevias2hwdcbx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb23aw0jfevias2hwdcbx.png" alt="Developers Garage logo" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>twiliohackathon</category>
      <category>javascript</category>
      <category>serverless</category>
      <category>kenticokontent</category>
    </item>
    <item>
      <title>Increase Your Discoverability With Keywords in Kontent</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Tue, 24 Mar 2020 05:10:53 +0000</pubDate>
      <link>https://dev.to/onyxprime/increase-your-discoverability-with-keywords-in-kontent-2p9c</link>
      <guid>https://dev.to/onyxprime/increase-your-discoverability-with-keywords-in-kontent-2p9c</guid>
      <description>&lt;p&gt;You come up with an amazing idea for a piece of content. You spend the next few days, week or longer creating, editing, fine-tuning your content. Once complete, you publish it to your medium of choice and wait for the reviews or read counts to go up, but they never do.&lt;/p&gt;

&lt;p&gt;You wonder what went wrong. Was the topic not that great of an idea? Are people not interested in the topic or am I just not as good of a writer as I thought I was? As a content creator, I feel your pain, as it's something I've been through and will continue go through in the future. Some of it might be true, as it is most times in my case 😋, but it is most likely a discoverability issue.&lt;/p&gt;

&lt;p&gt;As I continue to create content across different mediums, live streaming, video on-demand and written articles, I'm learning discoverability is really what keeps a lot of  content from getting from getting viewed. So, what can you do to help ensure your article gets seen, or noticed? &lt;/p&gt;

&lt;p&gt;Think about when you visit a site like Medium, or YouTube, what's the first thing you do? You enter the topic you're wanting to know or learn about in the search bar, right? At least that's what I do. Then the platform suggests content based on the search terms you entered. So, how do you get the platform to suggest your content? Well, most platforms offer some sort of tagging mechanism you can use to identify the keywords which can be used to best categorize your content.&lt;/p&gt;

&lt;p&gt;Figuring out these keywords is the next tricks, especially if you're not the original content creator. You could spend hours going through your content to identify those keywords, but I want to offer an alternative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keyword Extractor
&lt;/h2&gt;

&lt;p&gt;As part of our hackathon at our last DevRel reunion a few months ago, one of the teams worked on a keyword extractor to be used within Kentico Kontent. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh0joqbqfwsul32hp2vlu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh0joqbqfwsul32hp2vlu.gif" alt="Keyword extractor demo animated gif" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The keyword extractor custom element gives creators and editors an automated way to generate keywords for an item based on it's content. It allows editors to remove selective keywords, refresh the list manually and use different keyword selection algorithms. One algorithm, a pure JavaScript implementation, uses the &lt;a href="https://github.com/sleepycat/rapid-automated-keyword-extraction"&gt;rapid automatic keyword extraction&lt;/a&gt; (RAKE) algorithm. The other algorithm uses the &lt;a href="https://azure.microsoft.com/en-us/services/cognitive-services/text-analytics/"&gt;Microsoft Azure Text Analytics&lt;/a&gt; API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying
&lt;/h2&gt;

&lt;p&gt;Before we can use the keyword extractor within Kentico Kontent, it must be deployed to a public host. If you're running through a proof of concept, or just looking to test out the keyword extractor, and not ready to go through the process of setting up a production environment to host the keyword extractor, fear not. &lt;/p&gt;

&lt;p&gt;One of the steps the team took was to reduce the time it takes to get started using the Keyword Extractor was to automate a quick deployment using &lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt;. If you're not familiar with Netlify, it's an all-in-one platform for building, testing and deploying modern web projects. &lt;/p&gt;

&lt;p&gt;To deploy the project to Netlify, simply navigate to the deploying section in the &lt;a href="https://github.com/Kentico/kontent-custom-element-keyword-extractor#deploying"&gt;Keyword Extractor repository&lt;/a&gt;, click the "Deploy to Netlify" button and follow the instructions. Within 5 minutes, you'll have a fully deployed version of the Keyword Extractor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbfy38tn5q1izimz5h9tt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbfy38tn5q1izimz5h9tt.gif" alt="Deploying keyword extractor with Netlify" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Keyword Extractor
&lt;/h2&gt;

&lt;p&gt;To use the Keyword Extractor, a custom element will need to be added to the content type containing the content to be used. Instructions for adding the custom element can be found in the Kentico Kontent documentation. &lt;/p&gt;

&lt;p&gt;You will need 2 pieces of information to complete this step. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the URL where we deployed the code to in the above step&lt;/li&gt;
&lt;li&gt;a set of JSON parameters used to configure the Keyword Extractor
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
    "elements": [&lt;br&gt;
        "&amp;lt;codename of element to be used&amp;gt;"&lt;br&gt;
    ],&lt;br&gt;
    "azureKey": "&amp;lt;YOUR_AZURE_ACCESS_KEY&amp;gt;",&lt;br&gt;
    "debug": true&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;The "elements" are an array of the codenames for the elements containing the content to be searched for keywords. The "azureKey" is the API key for the Azure Text Analytics API and "debug" displays a debug panel on the content item used in troubleshooting. &lt;/p&gt;

&lt;p&gt;If you want to test the pure JavaScript implementation, remove "azureKey" from the JSON. If you do not want to show the debug panel, either set the value to "false",  or remove it from the JSON.&lt;/p&gt;

&lt;p&gt;Once the custom element is added and configured, it is ready for use by the content editors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;We've seen how we can save quite a bit of time in trying to figure out keywords to use for our content by setting up an automatic keyword extractor in Kentico Kontent. Now it's your turn to take these keywords and see how they can improve the discoverability of your content. &lt;/p&gt;

</description>
      <category>kenticokontent</category>
      <category>content</category>
      <category>keyword</category>
      <category>discoverability</category>
    </item>
    <item>
      <title>Is Jamstack Suitable for Anything More Than a Microsite?</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Mon, 03 Feb 2020 22:38:48 +0000</pubDate>
      <link>https://dev.to/onyxprime/is-jamstack-suitable-for-anything-more-than-a-microsite-fp1</link>
      <guid>https://dev.to/onyxprime/is-jamstack-suitable-for-anything-more-than-a-microsite-fp1</guid>
      <description>&lt;p&gt;In a world where user experience reigns supreme, a lone stack stands out providing fast, secure and usable sites: the Jamstack. Jamstack sites, or static sites, are great for blogs and marketing focused sites, but what about when content needs to be dynamic? Can the Jamstack handle these scenarios?&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Yes. Yes, it can.&lt;/p&gt;

&lt;p&gt;Before we go into how a static site can be dynamic, let's review what the Jamstack is.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Jamstack?
&lt;/h2&gt;

&lt;p&gt;If you're new to the Jamstack, it's not like most of the stacks you might be familiar with, like LAMP (Linux, Apache, MySQL, PHP/Perl/Python) or MEAN (MongoDB, Express.js, Angular, Node.js). It's not focused on a set of technologies, but rather a modern architectural pattern for "building websites and apps that delivers better performance, higher security, lower cost of scaling, and better developer experience." &lt;/p&gt;

&lt;p&gt;Jamstack stands for Javascript, APIs, and Markup. The power of the Jamstack comes with its core concept that sites are composed of static, pre-rendered HTML pages which can be enhanced using Javascript and APIs. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwg582qy1hduu8tc992ic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwg582qy1hduu8tc992ic.png" alt="Image of Jamstack acronym" width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This core concept is where Jamstack websites get their speed, they're pre-rendered. We don't have to wait for the web server to fetch data, most likely from another server, render the page and return it to the client. The pre-rendered page is returned as-is to the client. &lt;/p&gt;

&lt;p&gt;But wait... if the pages are pre-rendered, do we need a web server? No, a web server is no longer needed. We can use a content delivery network (CDN) to deliver our static pages. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F66gvyvyvip2x9va9yy3a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F66gvyvyvip2x9va9yy3a.png" alt="Image of traditional web request vs a static site web request" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how the Jamstack reduces the cost of scaling a site. One less server to manage, pay for and replicate as traffic increases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-rendering a Jamstack site
&lt;/h2&gt;

&lt;p&gt;Because we're deploying static HTML files, we could generate these files by hand. I would strongly discourage this method primarily because updates take more time and are error-prone due to duplication of markdown. &lt;/p&gt;

&lt;p&gt;Take the example where a new page is added to the navigation menu. All pages containing the navigation bar will need to be found and updated.&lt;/p&gt;

&lt;p&gt;Most of the time you'll want to use a static site generator (SSG), like Gatsby, Nuxt, or Jekyll, to pre-render the HTML pages. With an SSG we can create templates and components one time and then reference them on the pages that need them.&lt;/p&gt;

&lt;p&gt;Taking the same example used above, when a new item is added to the navigation bar, we only have to update it in the navigation bar component and all pages referencing this component will get the update once they're rebuilt. &lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic static site
&lt;/h2&gt;

&lt;p&gt;If the idea of a static site being dynamic sends your brain spinning 🤯, no worries, mine did the same when I first tried to understand how this could be possible. Static sites are great for blogs and microsites where content doesn't change too often, but what about when we need the content updated at a more rapid pace, or based on interactions with the user?&lt;/p&gt;

&lt;p&gt;Once I dove a little deeper into the concept of a dynamic static site, it made a little more sense. There are 2 ways a static site can be dynamic: during site pre-rendering and through user interactions with the site.&lt;/p&gt;

&lt;p&gt;During site pre-rendering, a static site generator can hit APIs to gather the necessary data from an external source and use templates to dynamically create the pages. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvb41yyaqjp99lsji5wz9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvb41yyaqjp99lsji5wz9.png" alt="Image of static site generator workflow" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider the example where you have a list of employees and there information stored in a content management system (CMS), such as &lt;a href="https://kontent.ai"&gt;Kentico Kontent&lt;/a&gt;, a static site generator can pull the list of employees from the CMS and build out an index page with a list of employees and individual pages for each employees details.&lt;/p&gt;

&lt;p&gt;The other scenario is when you need to dynamically update content based on some constantly changing piece of data, like the current temperature, the number of stars on your GitHub repo, or the cart on your favorite e-commerce site. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F35h2qjoj3gzcvdqbyq0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F35h2qjoj3gzcvdqbyq0y.png" alt="Image of browser getting data from 3rd-party APIs and CDN" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is accomplished by pre-rendering the page with default data. Once the page is loaded in the client, it can use Javascript to fetch the current data and update the page. &lt;/p&gt;

&lt;h2&gt;
  
  
  Want to know more?
&lt;/h2&gt;

&lt;p&gt;If you're interested in learning more, check out the videos from my &lt;a href="https://www.youtube.com/playlist?list=PLyLg0i-JALWpMMVGci5ULQKCfmcEV95Bt"&gt;LIVE sessions on Twitch&lt;/a&gt;, where we discuss the Jamstack and look at getting started using 2 different platforms, Gatsby + React and Gridsome + Vue.js. I also code LIVE on Twitch, &lt;a href="https://twitch.tv/developersgarage"&gt;DevelopersGarage&lt;/a&gt;, every week where we explore and learn about the Jamstack, as well as, other various development technologies and platforms.&lt;/p&gt;

</description>
      <category>jamstack</category>
      <category>javascript</category>
      <category>gatsby</category>
      <category>gridsome</category>
    </item>
    <item>
      <title>Deploying Your Blazor Application to Azure</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Fri, 03 Jan 2020 04:47:58 +0000</pubDate>
      <link>https://dev.to/onyxprime/deploying-your-blazor-application-to-azure-4b72</link>
      <guid>https://dev.to/onyxprime/deploying-your-blazor-application-to-azure-4b72</guid>
      <description>&lt;p&gt;&lt;em&gt;This article is part of series by &lt;a href="https://dev.to/ondrabus_94"&gt;Ondrej Polesny&lt;/a&gt; and myself. To catch-up, check out the previous articles.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You've created an amazing, interactive web application using the latest feature of ASP.NET, Blazor, but now what? How do you get it out there to show the world all your hard work? Where do you host it? How do you get it there?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, we'll show you how to deploy your Blazor application to Microsoft's cloud computing service, Azure. We'll also be using Visual Studio 2019 to publish/deploy the application. Visual Studio provides the ability to deploy your application to a folder, IIS, Azure, or other destinations, within the integrated development environment (IDE) reducing the steps it takes to get your application in front of your audience.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting up the environment
&lt;/h1&gt;

&lt;p&gt;Before we can deploy our application, we need to create and configure the environment to hold and serve the application. We'll be using services that fall under the free tier account usage within Azure. To see a list of everything available on the free tier account, go &lt;a href="https://azure.microsoft.com/en-us/free/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a web application in Azure
&lt;/h2&gt;

&lt;p&gt;Log in to the Azure &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;portal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While in the portal, click on the "+"  symbol on the menu on the left.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F389yci2nz6mh10bnodkq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F389yci2nz6mh10bnodkq.png" alt="Click on the plus"&gt;&lt;/a&gt;&lt;br&gt;
In the Marketplace, search for "Web App",&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8x7dz4m2s7vk4vejj959.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8x7dz4m2s7vk4vejj959.png" alt="Search for "&gt;&lt;/a&gt;&lt;br&gt;
and click "Create".&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fztlg2a7z6mozlat6fwzx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fztlg2a7z6mozlat6fwzx.png" alt="Click "&gt;&lt;/a&gt;&lt;br&gt;
On the "Basics" tab, ensure the subscription you wish to use is selected. We'll create a new resource group to contain our app service. A resource group is a collection of resources that share the same lifecycle, permissions and policies. Then provide an instance name for our application. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnwodszj0od5q3tlr8qxv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnwodszj0od5q3tlr8qxv.png" alt="Create web app basics tab"&gt;&lt;/a&gt;&lt;br&gt;
Scroll down the page, changing  "Operating System" to "Windows" and "Runtime Stack"to ."NET Core 3.0 (Current)". While .NET Core 3.1 (LTS) was released on December 3, 2019, at the time of this writing, web applications running under Windows on Azure do not currently support the latest version of .NET Core out of the box. Fear not, we can still run the latest version of .NET Core with a little extra configuration. We'll configure this later on in the article.&lt;/p&gt;

&lt;p&gt;Leave the remaining options set to their defaults. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: .NET Core 3.1 (LTS) is available out of the box for Linux operating systems on Azure.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0zimttp4lb1w5kalz6ey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0zimttp4lb1w5kalz6ey.png" alt="Create web app basics tab scrolled down"&gt;&lt;/a&gt;&lt;br&gt;
Now click "Review + create"&lt;/p&gt;

&lt;p&gt;Validate all the options are correct and click "Create". This kicks off the automation process within Azure which creates the web app environment within the selected regional datacenter. This process may take a few minutes depending on the current load within the datacenter.&lt;/p&gt;

&lt;p&gt;Once the deployment is complete, click on "Go to resource" to navigate to the newly created resource.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F27qdbp2bt3exodn09i9q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F27qdbp2bt3exodn09i9q.png" alt="Deployment completed screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring .NET Core 3.1 (LTS) Support
&lt;/h2&gt;

&lt;p&gt;With our web application created, we can now configure support for .NET Core 3.1 (LTS). While in the web application, navigate to the "Extensions" tab and click "Add" to open the  add extension window. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftgxbmshpbhc66i6a2i5d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftgxbmshpbhc66i6a2i5d.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Faszh8fmchjimronmzwsh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Faszh8fmchjimronmzwsh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Click on "Choose Extension" and select "ASP.NET Core 3.1 (x64) Runtime". &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6l09uehblfkja5ql3d0l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6l09uehblfkja5ql3d0l.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Click on "Legal Terms" and click "OK" to accept the terms. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7et2yuumfpv06m0iqar8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7et2yuumfpv06m0iqar8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Now click on "OK" under the "Add Extension" window.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpwc3p9cjibgv8kkr4rkc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpwc3p9cjibgv8kkr4rkc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
With the extension now added to our web application, we can run applications requiring .NET Core 3.1 without having to wait for Azure to support it. This same process can also be used when wanting to test new features only available within preview versions of .NET Core, like Blazor Web Assembly.&lt;/p&gt;

&lt;p&gt;We have 1 more step to complete before we can publish our Blazor application to Azure: update the configuration to x64. We must do this because we installed the x64 extension for .NET Core 3.1.&lt;/p&gt;

&lt;p&gt;Navigate to "Configuration" in the left menu, select the "General" tab and update the "Platform" to "64 bit".&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fek58x4b749by2dk85stw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fek58x4b749by2dk85stw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying the Blazor application
&lt;/h2&gt;

&lt;p&gt;With our Azure environment created and configure, we're now ready to deploy the Blazor application to it. The application we're deploying can be downloaded/cloned from here. We'll also grab one other file from our Azure web application service, the publish profile. &lt;/p&gt;

&lt;p&gt;Navigate to "Overview" on the left hand menu and click "Get publish profile".&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fz7w95ks6ncyh9pkq1d7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fz7w95ks6ncyh9pkq1d7i.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
The publish profile contains all the information Visual Studio needs (FTP location, credentials) to deploy our application to Azure.&lt;/p&gt;

&lt;p&gt;Now, open the Blazor application cloned in the previous step in Visual Studio 2019. Right-click the project "awesome-blazor-app" and click "Publish".&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxsdsz5882jbtru72finn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxsdsz5882jbtru72finn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Click "Import Profile..." and navigate to the location where you downloaded the publish profile from Azure a couple of steps ago. Select settings file and click import.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqdz8bicahed8eullipo4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqdz8bicahed8eullipo4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
With the publish profile imported, click on "Publish".  This kicks off the Visual Studio publish process, which will build the application in release mode and upon a successful build, will FTP the files to the Azure web application service we created earlier and launch our site in your default browser.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fk5fang8rwsehfeqfb03o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fk5fang8rwsehfeqfb03o.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;In this article, we learned how to create a web application environment within Azure to support a Blazor application and how to publish a Blazor application from Visual Studio to our Azure web application environment. We also learned how to use extensions in Azure to extend support for .NET Core 3.1 (LTS) to our web application. This is great, but it's not very maintainable, especially in a team environment. We'll fix this in an upcoming article where we automate the entire build and release process, removing bottlenecks and deployment silos. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other articles in the series:&lt;/strong&gt; &lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/onyxprime/what-is-this-blazor-everyone-s-talking-about-25mf/"&gt;#1 What is this Blazor everyone's talking about?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ondrabus_94/how-to-build-an-interactive-spa-with-blazor-4k8n"&gt;#2 How to Build an Interactive SPA with Blazor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;#3 Extending Interactive Blazor Site with Spatial Functions&lt;/li&gt;
&lt;li&gt;#4 Deploying your Blazor application to Azure&lt;/li&gt;
&lt;li&gt;#5 Automating the build and deploy of your Blazor application to Azure&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>blazor</category>
      <category>azure</category>
      <category>visualstudio</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>What is this Blazor everyone's talking about?</title>
      <dc:creator>Ryan Overton</dc:creator>
      <pubDate>Thu, 12 Dec 2019 15:53:15 +0000</pubDate>
      <link>https://dev.to/onyxprime/what-is-this-blazor-everyone-s-talking-about-25mf</link>
      <guid>https://dev.to/onyxprime/what-is-this-blazor-everyone-s-talking-about-25mf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;JavaScript has been labeled as the backbone of web application development allowing you to create beautiful, and functional, web applications. But for a .NET developer, like myself, working with JavaScript can feel like the wild, wild west. Fret no more! Blazor helps alleviate that feeling by allowing us to run C# code in the browser!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Read on to learn more about what Blazor is, as well as, the pros and cons of using Blazor.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Blazor?
&lt;/h1&gt;

&lt;p&gt;Blazor is a new single-page web application (SPA)  framework built on top of the .NET framework. It allows you, the .NET developer, to build the same great user interfaces as those using JavaScript, except with C#. This also means we can reuse existing .NET libraries and logic we've created, like for field validation.&lt;/p&gt;

&lt;p&gt;Now, there are those experienced developers out there, including yours truly, who remember the last framework to provide this feature, &lt;a href="https://en.wikipedia.org/wiki/Microsoft_Silverlight"&gt;Microsoft Silverlight&lt;/a&gt;, and it's fate. There was a caveat that came with using Microsoft Silverlight, though, and that was it required the installation of a compatible plugin into your browser. This is was a deal-breaker for a lot of web users, and still is, especially with the prevalence of mobile browsers. The good news for us today is Blazor does not come with this caveat.&lt;/p&gt;

&lt;p&gt;Blazor can run in 2 different modes, server-side and client-side. Each mode has different strengths and weaknesses making them useful for different scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Side Blazor
&lt;/h2&gt;

&lt;p&gt;Running Blazor in server-side mode means all execution of our C# code happens on the server. Once the code execution completes, updates to the user interface (UI) are immediately sent back to the client and merged into the document object model (DOM). Blazor uses SignalR, a real-time communication framework allowing server code to push content to "connected clients instantly as it becomes available, rather than having the server wait for a client to request new data."&lt;a href="https://docs.microsoft.com/en-us/aspnet/signalr/overview/getting-started/introduction-to-signalr#what-is-signalr"&gt;[1]&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Client-Side Blazor
&lt;/h2&gt;

&lt;p&gt;When using client-side mode, all code execution happens on the client and because everything happens on the client, all of the app's assets are deployed as static files. This means you can host the files on any service that can serve static files, like a content delivery network (CDN). To execute your C# code, Blazor uses WebAssembly (Wasm), a new technology that allows the execution of binary code inside most modern web browsers. &lt;/p&gt;

&lt;p&gt;To learn more about Wasm, check out this &lt;a href="https://medium.com/javascript-scene/what-is-webassembly-the-dawn-of-a-new-era-61256ec5a8f6"&gt;article&lt;/a&gt; by Eric Elliot.&lt;/p&gt;

&lt;h1&gt;
  
  
  JavaScript's not dead
&lt;/h1&gt;

&lt;p&gt;If you're a frontend developer who's reading this trying to keep up with all the new frameworks coming out these days, then you might be thinking Blazor, or Wasm for that matter, is trying to replace JavaScript. Let me put your worries at ease, as this is far from the truth. Wasm is meant to be a complement to JavaScript, not replacement.&lt;/p&gt;

&lt;p&gt;The team behind Blazor recognizes there is already a rich ecosystem of JavaScript libraries available to developers. Likewise, many companies and enterprises have a large investment in client-side libraries built throughout the many years before  This is why they provide &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-3.1#javascript-interop"&gt;JavaScript interoperability&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  The good, the bad and the ugly
&lt;/h1&gt;

&lt;p&gt;Alright, we've talked enough about what Blazor is and what it's not. Let's get to the pros and cons.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. A framework developers already know&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The team built Blazor around already used pieces of popular web development frameworks. So if you already have experience developing Razor Pages, MVC or Web APIs, the learning curve to Blazor is greatly reduced!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Faster page rendering&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because client-side Blazor is using WebAssembly to execute code and render the pages, we're able to run at near-native speeds, and the Blazor team is continuing to look for ways to increase these speeds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Client-side mode can run in an offline mode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When running your app in client-side mode, all the resources and libraries your app needs to run are downloaded to the client. This allows your application to run detached from the internet, or in an &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/hosting-models?view=aspnetcore-3.1#blazor-webassembly"&gt;offline mode&lt;/a&gt;. Something to also keep in mind, this is assuming your site doesn't need access to an external service to function, and if it does, you've accounted for the pre-loading, or persistence of  the data locally, until a connection can be made to the external service. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Server-side communication is efficient&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With Server-side Blazor, none of the code or libraries are sent to the client and only a small amount of JavaScript is sent over to bootstrap the application making it very efficient going across the wire. Server-side Blazor also uses SignalR to communicate between the server and client. SignalR uses web sockets to allow real-time back and forth communication, without having to wait for the client to make a request for new data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Code reuse&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Blazor implements .NET Standard 2.0, a formal specification of .NET APIs common across all .NET implementations. This means we can use the same code and libraries in the browser, on the server, or any other application implementing .NET Standard 2.0 and take advantage of the extensive, and growing set of libraries available in &lt;a href="https://www.nuget.org/"&gt;NuGet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Client-side runs in Browsers Sandbox security&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Long have users been worried about whether it's safe to run a web application or not due to concerns of malicious intent or data snooping. Blazor runs in Wasm and as such does not require any additional plugins or usage confirmations. It runs within the Browser Sandbox security context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. UI Component ecosystem from top component vendors&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many of the top component vendors, such as &lt;a href="https://www.telerik.com/blazor-ui"&gt;Telerik&lt;/a&gt;, &lt;a href="https://www.devexpress.com/blazor/"&gt;DevExpress&lt;/a&gt;, &lt;a href="https://www.grapecity.com/componentone/blazor"&gt;ComponentOne&lt;/a&gt;, and &lt;a href="https://www.syncfusion.com/blazor-components"&gt;SyncFusion&lt;/a&gt;, among others, have been following the development of Blazor and have already begun creating reusable UI components. These components further reduce the time it takes to get a working application out the door. &lt;/p&gt;

&lt;h2&gt;
  
  
  Cons
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. .NET Framework needs to be downloaded to the client&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Client-side mode executes the C# binaries in the context of the browser, and because of this client-side execution, a copy of the .NET Framework libraries are needed. This leads to the download size being larger and a longer initial app load time. Once the libraries are loaded, they can then be cached.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Client-side mode is still in preview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unlike server-side mode, which was released with the general availability of .NET Core 3.0, the client-side mode is still in preview. It is expected to be released in May 2020.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Only works on modern browsers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Due to the dependency on Wasm, older and non-standard browsers, like Internet Explorer and "thin clients", are unable to run client-side mode versions of Blazor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Debugging can be tricky&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because execution in client-side mode happens in binary on the client, custom tools are needed for debugging. These tools are currently limited in capabilities and can be cumbersome to set up. See the instructions &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/debug?view=aspnetcore-3.0"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Reduced performance benefits in server-side mode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unlike client-side mode, server-side mode requires a network connection between the client and server, and as such, any slowness in the network will negatively impact the performance of the application.&lt;/p&gt;

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

&lt;p&gt;It's never an easy decision when it comes to deciding on the technology for your team's next project and I hope I've provided you with some beneficial information when it comes time to evaluate your next web technology. While I would love to see Blazor take off like gangbusters, always use the right tool for the right job. 🙂&lt;/p&gt;

&lt;p&gt;To learn more about Blazor, head on over to the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-3.0"&gt;official documentation&lt;/a&gt;, or if you're itching to get your hands on some code and have the latest version of Visual Studio installed, just create a new project and select Blazor app. You can also view the official getting started guide &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/get-started"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other articles in the series:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;#1 What is this Blazor everyone's talking about?&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ondrabus_94/how-to-build-an-interactive-spa-with-blazor-4k8n"&gt;#2 How to Build an Interactive SPA with Blazor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ondrabus/avoiding-parking-fines-with-blazor-and-geolocation-572o"&gt;#3 Avoiding Parking Fines with Blazor and Geolocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/onyxprime/deploying-your-blazor-application-to-azure-4b72"&gt;#4 Deploying Your Blazor Application to Azure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Update 12/18/2019: Added link to article #2 in Blazor series.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Update 1/27/2020: Added link to article #3 and #4 in Blazor series.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>blazor</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
