<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ github pages - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ github pages - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 30 May 2026 14:18:07 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/github-pages/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Deploy Next.js Apps to Github Pages ]]>
                </title>
                <description>
                    <![CDATA[ In this article, I will walk you through the process of publishing a Next.js application on GitHub Pages.  What makes this guide particularly helpful is that I'll teach you how to integrate with GitHub Actions, too. This means your application will b... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-deploy-next-js-app-to-github-pages/</link>
                <guid isPermaLink="false">66bc4d0460ad5c1520c16683</guid>
                
                    <category>
                        <![CDATA[ deployment ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub Actions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ github pages ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Next.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Matéu.sh ]]>
                </dc:creator>
                <pubDate>Wed, 24 Jan 2024 22:46:53 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/Splash.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, I will walk you through the process of publishing a Next.js application on GitHub Pages. </p>
<p>What makes this guide particularly helpful is that I'll teach you how to integrate with GitHub Actions, too. This means your application will be automatically deployed every time you push code to your GitHub repository.</p>
<p>We'll just focus on deployment rather than building the entire Next.js app from scratch. For our example project, we'll use one from a previous article I wrote on freeCodeCamp in my article <a target="_blank" href="https://www.freecodecamp.org/news/how-to-make-2048-game-in-react/">How to Build 2048 Game in React</a>. I recently upgraded the codebase to use React 18 and added the Next.js framework.</p>
<p>If you want to see the end result of before reading the whole article, you can <a target="_blank" href="https://mateuszsokola.github.io/2048-in-react/">check it here</a>.</p>
<p>As I mentioned above, we're using a project I made in my previous tutorial – and so that you can use it here, you can find its <a target="_blank" href="https://github.com/mateuszsokola/2048-in-react/">source code on Github</a>. Feel free to clone or fork this repository, and just follow the steps in the tutorial to make it with me. </p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we start, make sure you know a little bit about React and Next.js. We'll also be using GitHub, so it's important to understand some basics. You don't have to be an expert, just have some basic experience with these things.</p>
<h2 id="heading-brief-introduction">Brief Introduction</h2>
<p>Today we are going to explore two new things – GitHub Actions and GitHub Pages. If you haven't heard of them, let me quickly explain:  </p>
<p><strong>GitHub Actions</strong> are like little workflows that can do tasks on your projects. It's like having a helper that automatically does things you tell it to do. You can use Actions to run tests, for quality checks, or to build your application. In our case, we're going to use these workflows to publish my <a target="_blank" href="https://mateuszsokola.github.io/2048-in-react/">2048 Game</a> on GitHub Pages.</p>
<p>Now, what are <strong>GitHub Pages</strong>? Think of them like a web hosting option for developers and open source projects. You can use GitHub Pages to share your portfolios, host websites of your open-source projects, or just publish your pet projects like we're doing today.  </p>
<p>If you want to learn more, you can read more on their official websites:</p>
<ul>
<li><a target="_blank" href="https://github.com/features/actions">GitHub Actions</a></li>
<li><a target="_blank" href="https://pages.github.com/">GitHub Pages</a></li>
</ul>
<p>Now let's get our hands dirty.</p>
<h2 id="heading-step-1-activate-github-pages-for-your-repository">Step 1 – Activate GitHub Pages for Your Repository</h2>
<p>To publish our Next.js application, we have to activate GitHub Pages for our repository. Let's navigate to the Settings tab (1 in the image below), select <em>Pages</em> from the menu on the left-hand side (2), and find the dropdown menu that allows us to specify the deployment <em>Source</em> (3).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/GH-Pages---Step-1a.png" alt="Image" width="600" height="400" loading="lazy">
<em>GitHub Project Settings</em></p>
<p>Now let's change the deployment <em>Source</em> to <em>GitHub Actions</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/GH-Pages---Step-1b.png" alt="Image" width="600" height="400" loading="lazy">
<em>GitHub Project Settings – GitHub Pages configuration</em></p>
<p>From now on, our project has a dedicated page. We only need to create an action that will publish content there.</p>
<h2 id="heading-step-2-configure-the-nextjs-build-process">Step 2 – Configure the Next.js Build Process</h2>
<p>Before deploying the Next.js app, it's important to change the build output. By default, Next.js uses Node.js to run the application, and this is incompatible with GitHub Pages. </p>
<p>GitHub Pages is designed to host static files, which means we can publish only HTML, CSS, JavaScript (and other static files) there. So we'll need to enable static page generation in Next.js. </p>
<p>To do so, we will change the output mode to <code>export</code> inside <code>next.config.js</code>:</p>
<pre><code class="lang-js"><span class="hljs-comment">/** <span class="hljs-doctag">@type <span class="hljs-type">{import('next').NextConfig}</span> </span>*/</span>
<span class="hljs-keyword">const</span> nextConfig = {
  <span class="hljs-attr">output</span>: <span class="hljs-string">"export"</span>,  <span class="hljs-comment">// &lt;=== enables static exports</span>
  <span class="hljs-attr">reactStrictMode</span>: <span class="hljs-literal">true</span>,
};

<span class="hljs-built_in">module</span>.exports = nextConfig;
</code></pre>
<p>Now after running <code>next build</code>, Next.js will generate an <code>out</code> folder containing static assets for our application. In the next steps, we will take this directory and upload it to GitHub Pages.</p>
<p>Side note for seasoned Next.js developers: you can use <a target="_blank" href="https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-props"><code>getStaticProps</code></a> and <a target="_blank" href="https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-paths"><code>getStaticPaths</code></a> to generate static files for each page in your <code>pages</code> directory.</p>
<h2 id="heading-step-3-configure-base-path-to-fix-missing-images">Step 3 – Configure Base Path to Fix Missing Images</h2>
<p>Github publishes Pages under a sub-path of a domain and takes the project name as a sub-path. It sounds confusing, so let's take a URL to my 2048 game as an example:</p>
<pre><code class="lang-bash">https://mateuszsokola.github.io/2048-in-react/
</code></pre>
<p>As you can see, Github assigned a dedicated subdomain for me called <em>mateuszsokola</em> (after my username). But the project is published under the sub-path, which in my case is <code>/2048-in-react</code>. Unfortunately, this will lead to issues with missing images and styles. </p>
<p>By default, Next.js maps all static assets the domain. This means that the <code>favicon.ico</code> file will be resolved to <code>mateuszsokola.github.io/favicon.ico</code> instead of <code>mateuszsokola.github.io/2048-in-react/favicon.icon</code>. </p>
<p>To fix this, we can set up a path prefix by adding <code>basePath</code> inside the <code>next.config.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-comment">/** <span class="hljs-doctag">@type <span class="hljs-type">{import('next').NextConfig}</span> </span>*/</span>
<span class="hljs-keyword">const</span> nextConfig = {
  <span class="hljs-attr">basePath</span>: <span class="hljs-string">"/2048-in-react"</span>,
  <span class="hljs-attr">output</span>: <span class="hljs-string">"export"</span>,
  <span class="hljs-attr">reactStrictMode</span>: <span class="hljs-literal">true</span>,
};

<span class="hljs-built_in">module</span>.exports = nextConfig;
</code></pre>
<p>In my case, it is <code>/2048-in-react</code> since my project is called <code>2048-in-react</code>.<br><strong>Remember to include the (<code>/</code>) at beginning of the path.</strong></p>
<h2 id="heading-step-4-configure-github-actions">Step 4 – Configure Github Actions</h2>
<p>Now it's time to set up Github Actions for Next.js deployment. Reusability is a good practice so I divided the deployment into two separate actions:</p>
<ul>
<li><code>setup-node</code> action – This action is responsible for setting up Node.js and installing all dependencies. Having a standalone action for the Node.js setup enables us to reuse it for other pipelines. For example, in my 2048 Game, I have pipelines that run <a target="_blank" href="https://github.com/mateuszsokola/2048-in-react/blob/master/.github/workflows/lint.yml">code linter</a> and <a target="_blank" href="https://github.com/mateuszsokola/2048-in-react/blob/master/.github/workflows/test.yml">tests</a>. Likely you will have more than one action as well.</li>
<li><code>publish</code> action – This action handles the build process and publishes the Next.js app to GitHub Pages each time we merge code into the <code>main</code> branch.</li>
</ul>
<p>Now, you can understand why it's beneficial to split the deployment into two actions. </p>
<p>Let me begin by explaining the <code>setup-node</code> action. Here is the code:</p>
<pre><code class="lang-yml"><span class="hljs-comment"># File: .github/workflows/setup-node/action.yml</span>
<span class="hljs-attr">name:</span> <span class="hljs-string">setup-node</span>
<span class="hljs-attr">description:</span> <span class="hljs-string">"Setup Node.js ⚙️ - Cache dependencies ⚡ - Install dependencies 🔧"</span>
<span class="hljs-attr">runs:</span>
  <span class="hljs-attr">using:</span> <span class="hljs-string">"composite"</span>
  <span class="hljs-attr">steps:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Setup</span> <span class="hljs-string">Node.js</span> <span class="hljs-string">⚙️</span>
      <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/setup-node@v4</span>
      <span class="hljs-attr">with:</span>
        <span class="hljs-attr">node-version:</span> <span class="hljs-number">20</span>

    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Cache</span> <span class="hljs-string">dependencies</span> <span class="hljs-string">⚡</span>
      <span class="hljs-attr">id:</span> <span class="hljs-string">cache_dependencies</span>
      <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/cache@v3</span>
      <span class="hljs-attr">with:</span>
        <span class="hljs-attr">path:</span> <span class="hljs-string">node_modules</span>
        <span class="hljs-attr">key:</span> <span class="hljs-string">node-modules-${{</span> <span class="hljs-string">hashFiles('package-lock.json')</span> <span class="hljs-string">}}</span>

    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">dependencies</span> <span class="hljs-string">🔧</span>
      <span class="hljs-attr">shell:</span> <span class="hljs-string">bash</span>
      <span class="hljs-attr">if:</span> <span class="hljs-string">steps.cache_dependencies.outputs.cache-hit</span> <span class="hljs-type">!=</span> <span class="hljs-string">'true'</span>
      <span class="hljs-attr">run:</span> <span class="hljs-string">npm</span> <span class="hljs-string">ci</span>
</code></pre>
<p><strong>Important</strong>: Put this file in the  <code>.github/workflows/setup-node</code> directory in your project. Make sure to call the file <code>action.yml</code>.</p>
<p>What does this code do?</p>
<ul>
<li>It declares a <code>composite</code> action. The <code>composite</code> action allows you to bundle multiple workflow steps into a single action, combining multiple run commands into a single reusable action.</li>
<li>It creates a new build environment and sets up Node.js 20 there.</li>
<li>It installs npm dependencies and uses a caching mechanism to speed up this process.</li>
</ul>
<p>These are the most important parts of the <code>setup-node</code> action. Now, let's move on to the last action, which is <code>publish</code>.</p>
<pre><code class="lang-yml"><span class="hljs-comment"># File: .github/workflows/publish.yml</span>
<span class="hljs-attr">name:</span> <span class="hljs-string">publish-to-github-pages</span>
<span class="hljs-attr">on:</span>
  <span class="hljs-attr">push:</span>
    <span class="hljs-attr">branches:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">master</span>

<span class="hljs-attr">permissions:</span>
  <span class="hljs-attr">contents:</span> <span class="hljs-string">read</span>
  <span class="hljs-attr">pages:</span> <span class="hljs-string">write</span>
  <span class="hljs-attr">id-token:</span> <span class="hljs-string">write</span>

<span class="hljs-attr">concurrency:</span>
  <span class="hljs-attr">group:</span> <span class="hljs-string">"pages"</span>
  <span class="hljs-attr">cancel-in-progress:</span> <span class="hljs-literal">false</span>

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">build:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>

    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">🛎️</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Setup</span> <span class="hljs-string">Node.js</span> <span class="hljs-string">⚙️</span> <span class="hljs-bullet">-</span> <span class="hljs-string">Cache</span> <span class="hljs-string">dependencies</span> <span class="hljs-string">⚡</span> <span class="hljs-bullet">-</span> <span class="hljs-string">Install</span> <span class="hljs-string">dependencies</span> <span class="hljs-string">🔧</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">./.github/workflows/setup-node</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Setup</span> <span class="hljs-string">Pages</span> <span class="hljs-string">⚙️</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/configure-pages@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">static_site_generator:</span> <span class="hljs-string">next</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Build</span> <span class="hljs-string">with</span> <span class="hljs-string">Next.js</span> <span class="hljs-string">🏗️</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">npx</span> <span class="hljs-string">next</span> <span class="hljs-string">build</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Upload</span> <span class="hljs-string">artifact</span> <span class="hljs-string">📡</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/upload-pages-artifact@v3</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">path:</span> <span class="hljs-string">./out</span>

  <span class="hljs-attr">deploy:</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">name:</span> <span class="hljs-string">github-pages</span>
      <span class="hljs-attr">url:</span> <span class="hljs-string">${{</span> <span class="hljs-string">steps.deployment.outputs.page_url</span> <span class="hljs-string">}}</span>

    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">needs:</span> <span class="hljs-string">build</span>

    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Publish</span> <span class="hljs-string">to</span> <span class="hljs-string">GitHub</span> <span class="hljs-string">Pages</span> <span class="hljs-string">🚀</span>
        <span class="hljs-attr">id:</span> <span class="hljs-string">deployment</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/deploy-pages@v4</span>
</code></pre>
<p>Put this file in the <code>.github/workflows</code> directory in your project. You can name the file as you like – I called it <code>publish.yml</code>.</p>
<p>What does this code do?</p>
<ul>
<li>This action is executed when code is pushed or merged into the <code>main</code> branch.</li>
<li>It uses the <code>setup-node</code> action to set up the environment.</li>
<li>The action has two stages: in the first stage, the Next.js app is bundled. In the second stage, we upload the artifacts from the first stage to GitHub Pages.</li>
</ul>
<p>These are the most important aspects of the deployment pipeline. I skipped the permissions and concurrency setup since they remain unchanged for all deployments. </p>
<p>Now, your action is ready to use.</p>
<h2 id="heading-commit-and-push">Commit and Push</h2>
<p>After committing and pushing your changes to the <code>main</code> branch, GitHub will automatically initiate the deployment to GitHub Pages. </p>
<p>To inspect the process, navigate to the <em>Actions</em> tab (1 in the image below), and select the <em>publish-to-github-pages</em> action from the menu on the left hand side (2)<em>.</em> You will see a all your deployments on the screen (they are called <em>workflows</em>).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/GH-Pages---Summary.png" alt="Image" width="600" height="400" loading="lazy">
<em>GitHub Actions – Workflows responsible for publishing to GitHub Pages</em></p>
<p>Now, we need to select the first one of those workflows, and you will see a two-stage deployment. In the <em>deploy</em> stage, you can find a link to your website on GitHub Pages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/GH-Pages---SummaryCI.png" alt="Image" width="600" height="400" loading="lazy">
<em>GitHub Project Workflow – Successful deployment</em></p>
<h2 id="heading-wrapping-up"><strong>Wrapping Up</strong></h2>
<p>Github Pages isn't sufficient for hosting websites with millions of views. But it's an excellent choice for building your portfolio or hosting a website for your open-source project. </p>
<p>Nowadays, there are many free options to host our websites, but I wanted to show you this alternative. GitHub Pages is built by developers for developers – you can consider it a developer's natural habitat. I think every developer should be familiar with it.</p>
<p>I hope this article will be a gentle push towards learning more about GitHub Actions. Feel free to experiment with different approaches and try to create your own. Every application needs to be shipped and consider this article just as a starting point.</p>
<p>Here are the resources:</p>
<ul>
<li><a target="_blank" href="https://mateuszsokola.github.io/2048-in-react/">2048 Game on Github Pages</a></li>
<li><a target="_blank" href="https://github.com/mateuszsokola/2048-in-react/">Source code on Github</a>. It'd mean the world to me if you star ⭐ this repository.</li>
</ul>
<p>If this article helped you, please <a target="_blank" href="https://twitter.com/msokola">let me know on Twitter</a>. Educators, like me, often feel like we are speaking into a vacuum and nobody cares what we teach. A simple "shoutout" shows it was worth an effort and inspires me to work even harder to create more content like this.</p>
<p>Feel free to share this article on your social media. </p>
<p>Thank you.</p>
<p>If you wish to know more about me – My name is Matéush. I am a software engineer and digital nomad. I can say I have an extraordinary career. I lived in three different countries and worked in various environments from startups to large enterprises. </p>
<p>Recently I started to share advice on <a target="_blank" href="https://www.mateu.sh/?ref=freecodecamp.org">growing a software developer career</a>. I believe I created my blog for my younger self — a bit lost, motivated to become one of the best developers, and seeking a path into the world of “big tech”.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Host an Angular Application on GitHub Pages with Travis CI ]]>
                </title>
                <description>
                    <![CDATA[ By Rodrigo Kamada In this article, we'll create an application using the latest version of Angular. Then we'll host it on the GitHub Pages static website service using the continuous integration tool Travis CI to deploy the application. Prerequisites... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/host-an-angular-application-on-github-pages-with-travis-ci/</link>
                <guid isPermaLink="false">66d460c57df3a1f32ee7f88d</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ github pages ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Travis CI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 19 Apr 2022 10:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/04/angular-travisci-cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Rodrigo Kamada</p>
<p>In this article, we'll create an application using the latest version of Angular. Then we'll host it on the GitHub Pages static website service using the continuous integration tool Travis CI to deploy the application.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you start, you need to install and configure the tools below to create the Angular application.</p>
<ul>
<li><a target="_blank" href="https://git-scm.com/">Git</a>: Git is a distributed version control system that we'll use to sync the repository.</li>
<li><a target="_blank" href="https://nodejs.org/">Node.js and npm</a>: Node.js is a JavaScript code runtime software based on Google's V8 engine. npm is a package manager for Node.js (Node Package Manager). We'll use these to build and run the Angular application and install the libraries.</li>
<li><a target="_blank" href="https://angular.io/cli">Angular CLI</a>: Angular CLI is a command line utility tool for Angular which we'll use to create the base structure of the Angular application.</li>
<li>An IDE (like <a target="_blank" href="https://code.visualstudio.com/">Visual Studio Code</a> or <a target="_blank" href="https://www.jetbrains.com/webstorm/">WebStorm</a>): an IDE (Integrated Development Environment) is a tool with a graphical interface that helps us develop applications. Here, we'll use one to develop the Angular application.</li>
</ul>
<h2 id="heading-getting-started">Getting started</h2>
<h3 id="heading-create-and-configure-your-account-on-github">Create and configure your account on GitHub</h3>
<p><a target="_blank" href="https://github.com/">GitHub</a> is a source code and file storage service with version control using the Git tool. And <a target="_blank" href="https://pages.github.com/">GitHub Pages</a> is a static file hosting service using a public repository.</p>
<p>First, you'll need to create an account on GitHub if you don't have one already. Visit <a target="_blank" href="https://github.com/">https://github.com/</a> and click on the button <em>Sign up</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Fill in the fields for Username, Email address, and Password, click on the button Verify to solve the challenge, and then click on the button Create account.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next, we'll generate the token that will be used in Travis CI. Click on the menu with the avatar and click on the menu Settings.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Click on the menu Developer settings.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Click on the menu Personal access tokens.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step5.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Click on the button Generate new token.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step6.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Fill in the field Note, select the option repo and click on the button Create token.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step7.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Copy the generated token. In my case, the token <code>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</code> was generated because this token will be configured in Travis CI.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step8.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Let's create the repository. Click on the menu with the avatar and click on the menu Your repositories.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step9.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Click on the button New.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step10.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Fill in the field Repository name and click on the button Create repository.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step11.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Ready! Account created, token generated, and repository <a target="_blank" href="https://github.com/rodrigokamada/angular-travisci"><code>https://github.com/rodrigokamada/angular-travisci</code></a> created.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/github-step12.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-create-and-configure-your-account-on-travis-ci">Create and configure your account on Travis CI</h3>
<p><a target="_blank" href="https://www.travis-ci.com/">Travis CI</a> is a deployment service integrated with GitHub.</p>
<p>First, you'll need to create a Travis CI account if you don't already have one. Visit <a target="_blank" href="https://travis-ci.com/">https://travis-ci.com/</a> and click on the button Sign up.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/travisci-step1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Click on the button SIGN IN WITH GITHUB to sign in with your GitHub account.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/travisci-step2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If Travis CI requests permission to list the GitHub repositories, accept the request. Click on the repository link angular-travisci.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/travisci-step3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Let's set up the GitHub access token. Click on the menu More options and click on the menu Settings.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/travisci-step4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Fill in the field NAME with the value GITHUB_TOKEN, VALUE with the value of your token generated on GitHub, and click on the button Add.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/travisci-step5.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Ready! Account created and repository configured.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/travisci-step6.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-create-your-angular-application">Create your Angular application</h3>
<p><a target="_blank" href="https://angular.io/">Angular</a> is a development platform for building Web, mobile, and desktop applications using HTML, CSS and TypeScript (JavaScript). Currently, Angular is at version 13 and Google is the main maintainer of the project.</p>
<p>Let's create the application with the Angular base structure using the <code>@angular/cli</code> with the route file and the SCSS style format.</p>
<pre><code class="lang-powershell">? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? SCSS   [ <span class="hljs-type">https</span>://<span class="hljs-type">sass</span>-<span class="hljs-type">lang.com</span>/<span class="hljs-type">documentation</span>/<span class="hljs-type">syntax</span><span class="hljs-comment">#scss                ]</span>
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">README.md</span> (<span class="hljs-number">1061</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">.editorconfig</span> (<span class="hljs-number">274</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">.gitignore</span> (<span class="hljs-number">604</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">angular.json</span> (<span class="hljs-number">3267</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">package.json</span> (<span class="hljs-number">1078</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">tsconfig.json</span> (<span class="hljs-number">783</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">.browserslistrc</span> (<span class="hljs-number">703</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">karma.conf.js</span> (<span class="hljs-number">1433</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">tsconfig.app.json</span> (<span class="hljs-number">287</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">tsconfig.spec.json</span> (<span class="hljs-number">333</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">favicon.ico</span> (<span class="hljs-number">948</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">index.html</span> (<span class="hljs-number">301</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">main.ts</span> (<span class="hljs-number">372</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">polyfills.ts</span> (<span class="hljs-number">2820</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">styles.scss</span> (<span class="hljs-number">80</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">test.ts</span> (<span class="hljs-number">743</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">assets</span>/<span class="hljs-type">.gitkeep</span> (<span class="hljs-number">0</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">environments</span>/<span class="hljs-type">environment.prod.ts</span> (<span class="hljs-number">51</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">environments</span>/<span class="hljs-type">environment.ts</span> (<span class="hljs-number">658</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">app</span>/<span class="hljs-type">app</span>-<span class="hljs-type">routing.module.ts</span> (<span class="hljs-number">245</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">app</span>/<span class="hljs-type">app.module.ts</span> (<span class="hljs-number">393</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">app</span>/<span class="hljs-type">app.component.scss</span> (<span class="hljs-number">0</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">app</span>/<span class="hljs-type">app.component.html</span> (<span class="hljs-number">23809</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">app</span>/<span class="hljs-type">app.component.spec.ts</span> (<span class="hljs-number">1087</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
<span class="hljs-type">CREATE</span> <span class="hljs-type">angular</span>-<span class="hljs-type">travisci</span>/<span class="hljs-type">src</span>/<span class="hljs-type">app</span>/<span class="hljs-type">app.component.ts</span> (<span class="hljs-number">221</span> <span class="hljs-built_in">byte</span><span class="hljs-type">s</span>)
✔ <span class="hljs-type">Packages</span> <span class="hljs-type">installed</span> <span class="hljs-type">successfully.</span>
    <span class="hljs-type">Successfully</span> <span class="hljs-type">initialized</span> <span class="hljs-type">git.</span>
</code></pre>
<p>Create the <code>.travis.yml</code> file.</p>
<pre><code class="lang-powershell">touch .travis.yml
</code></pre>
<p>Configure the <code>.travis.yml</code> file with the content below:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">notifications:</span>
  <span class="hljs-attr">email:</span>
    <span class="hljs-attr">recipients:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">rodrigo@kamada.com.br</span>

<span class="hljs-attr">language:</span> <span class="hljs-string">node_js</span>

<span class="hljs-attr">node_js:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-number">16</span>

<span class="hljs-attr">before_script:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">npm</span> <span class="hljs-string">install</span>

<span class="hljs-attr">script:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">npm</span> <span class="hljs-string">run</span> <span class="hljs-string">test:headless</span>

<span class="hljs-attr">before_deploy:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">npm</span> <span class="hljs-string">run</span> <span class="hljs-string">build:prod</span>

<span class="hljs-attr">deploy:</span>
  <span class="hljs-attr">provider:</span> <span class="hljs-string">pages</span>
  <span class="hljs-attr">skip_cleanup:</span> <span class="hljs-literal">true</span>
  <span class="hljs-attr">github_token:</span> <span class="hljs-string">$GITHUB_TOKEN</span>
  <span class="hljs-attr">local_dir:</span> <span class="hljs-string">dist/angular-travisci</span>
  <span class="hljs-attr">on:</span>
    <span class="hljs-attr">branch:</span> <span class="hljs-string">main</span>
</code></pre>
<p>Change the <code>package.json</code> file and add the scripts below. Replace the <code>rodrigokamada</code> value with your GitHub username.</p>
<pre><code class="lang-json">  <span class="hljs-string">"build:prod"</span>: <span class="hljs-string">"ng build --prod --base-href https://rodrigokamada.github.io/angular-travisci/"</span>,
  <span class="hljs-string">"test:headless"</span>: <span class="hljs-string">"ng test --watch=false --browsers=ChromeHeadless"</span>
</code></pre>
<p>Change the <code>src/app/app.component.spec.ts</code> file and remove the tests <code>should have as title 'angular-travisci'</code> and <code>should render title</code>.</p>
<p>Run the test with the command below:</p>
<pre><code class="lang-powershell">npm run test:headless

&gt; angular<span class="hljs-literal">-travisci</span>@<span class="hljs-number">1.0</span>.<span class="hljs-number">0</span> test:headless
&gt; ng test -<span class="hljs-literal">-watch</span>=false -<span class="hljs-literal">-browsers</span>=ChromeHeadless

⠋ Generating browser application bundles (phase: setup)...Compiling @angular/core/testing : es2015 as esm2015
Compiling @angular/compiler/testing : es2015 as esm2015
Compiling @angular/platform<span class="hljs-literal">-browser</span>/testing : es2015 as esm2015
Compiling @angular/common/testing : es2015 as esm2015
Compiling @angular/platform<span class="hljs-literal">-browser</span><span class="hljs-literal">-dynamic</span>/testing : es2015 as esm2015
Compiling @angular/router/testing : es2015 as esm2015
⠸ Generating browser application bundles (phase: building)...<span class="hljs-number">05</span> <span class="hljs-number">09</span> <span class="hljs-number">2021</span> <span class="hljs-number">19</span>:<span class="hljs-number">40</span>:<span class="hljs-number">04.329</span>:INFO [<span class="hljs-type">karma</span>-<span class="hljs-type">server</span>]: Karma v6.<span class="hljs-number">3.4</span> server started at http://localhost:<span class="hljs-number">9876</span>/
<span class="hljs-number">05</span> <span class="hljs-number">09</span> <span class="hljs-number">2021</span> <span class="hljs-number">19</span>:<span class="hljs-number">40</span>:<span class="hljs-number">04.331</span>:INFO [<span class="hljs-type">launcher</span>]: Launching browsers ChromeHeadless with concurrency unlimited
<span class="hljs-number">05</span> <span class="hljs-number">09</span> <span class="hljs-number">2021</span> <span class="hljs-number">19</span>:<span class="hljs-number">40</span>:<span class="hljs-number">04.369</span>:INFO [<span class="hljs-type">launcher</span>]: Starting browser ChromeHeadless
✔ Browser application bundle generation complete.
<span class="hljs-number">05</span> <span class="hljs-number">09</span> <span class="hljs-number">2021</span> <span class="hljs-number">19</span>:<span class="hljs-number">40</span>:<span class="hljs-number">09.704</span>:INFO [<span class="hljs-type">Chrome</span> <span class="hljs-type">Headless</span> <span class="hljs-number">92.0</span><span class="hljs-type">.4515.159</span> (<span class="hljs-type">Linux</span> <span class="hljs-type">x86_64</span>)]: Connected on socket NUtJhjavb1JvssqOAAAB with id <span class="hljs-number">25989029</span>
Chrome Headless <span class="hljs-number">92.0</span>.<span class="hljs-number">4515.159</span> (Linux x86_64): Executed <span class="hljs-number">1</span> of <span class="hljs-number">1</span> SUCCESS (<span class="hljs-number">0.068</span> secs / <span class="hljs-number">0.042</span> secs)
TOTAL: <span class="hljs-number">1</span> SUCCESS
</code></pre>
<p>Run the application with the command below. Access the URL <code>http://localhost:4200/</code> and check if the application is working.</p>
<pre><code class="lang-powershell">npm <span class="hljs-built_in">start</span>

&gt; angular<span class="hljs-literal">-travisci</span>@<span class="hljs-number">1.0</span>.<span class="hljs-number">0</span> <span class="hljs-built_in">start</span>
&gt; ng serve

✔ Browser application bundle generation complete.

Initial Chunk Files | Names         |      Size
vendor.js           | vendor        |   <span class="hljs-number">2.39</span> MB
polyfills.js        | polyfills     | <span class="hljs-number">128.51</span> kB
main.js             | main          |   <span class="hljs-number">8.89</span> kB
runtime.js          | runtime       |   <span class="hljs-number">6.63</span> kB
styles.css          | styles        |   <span class="hljs-number">1.18</span> kB

                    | Initial Total |   <span class="hljs-number">2.53</span> MB

Build at: <span class="hljs-number">2021</span><span class="hljs-literal">-09</span><span class="hljs-literal">-05T22</span>:<span class="hljs-number">35</span>:<span class="hljs-number">38.010</span>Z - Hash: a4cfc9149589386eca5b - Time: <span class="hljs-number">39997</span>ms

** Angular Live Development Server is listening on localhost:<span class="hljs-number">4200</span>, open your browser on http://localhost:<span class="hljs-number">4200</span>/ **


✔ Compiled successfully.
</code></pre>
<p>Build the application with the command below:</p>
<pre><code class="lang-powershell">npm run build:prod

&gt; angular<span class="hljs-literal">-travisci</span>@<span class="hljs-number">1.0</span>.<span class="hljs-number">0</span> build:prod
&gt; ng build -<span class="hljs-literal">-configuration</span> production -<span class="hljs-literal">-base</span><span class="hljs-literal">-href</span> https://rodrigokamada.github.io/angular<span class="hljs-literal">-travisci</span>/

✔ Browser application bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.

Initial Chunk Files           | Names         |      Size
main.c678fa8750e7c769.js      | main          | <span class="hljs-number">177.63</span> kB
polyfills.<span class="hljs-number">6</span>d7801353e02e327.js | polyfills     |  <span class="hljs-number">36.21</span> kB
runtime.b136bda8a38c4f2e.js   | runtime       |   <span class="hljs-number">1.06</span> kB
styles.ef46db3751d8e999.css   | styles        |   <span class="hljs-number">0</span> bytes

                              | Initial Total | <span class="hljs-number">214.90</span> kB

Build at: <span class="hljs-number">2021</span><span class="hljs-literal">-09</span><span class="hljs-literal">-05T22</span>:<span class="hljs-number">42</span>:<span class="hljs-number">19.525</span>Z - Hash: <span class="hljs-number">83</span>bfffc079b083727ca4 - Time: <span class="hljs-number">26030</span>ms
</code></pre>
<p>Syncronize the application on the GitHub repository that you created.</p>
<p>Ready! After synchronizing the application on the GitHub repository, Travis CI builds the application and synchronizes on the branch <code>gh-pages</code>. </p>
<p>Access the URL <a target="_blank" href="https://rodrigokamada.github.io/angular-travisci/"><code>https://rodrigokamada.github.io/angular-travisci/</code></a> and check if the application is working. Replace the <code>rodrigokamada</code> value with your GitHub username.</p>
<p>And that's it! The application repository is available at <a target="_blank" href="https://github.com/rodrigokamada/angular-travisci">https://github.com/rodrigokamada/angular-travisci</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Summarizing what was covered in this article:</p>
<ul>
<li>We created an account on GitHub.</li>
<li>We created an access token on GitHub.</li>
<li>We created a repository on GitHub.</li>
<li>We created an account on Travis CI.</li>
<li>We configured the GitHub access token on Travis CI.</li>
<li>We create an Angular application.</li>
</ul>
<p>You can use this article to create your personal website and have an online portfolio.</p>
<p>Thank you for reading and I hope you enjoyed the article!</p>
<p>To stay updated whenever I post new articles, follow me on <a target="_blank" href="https://twitter.com/rodrigokamada">Twitter</a>.</p>
<p>This tutorial was posted on my <a target="_blank" href="https://rodrigo.kamada.com.br/share/blog/hospedando-uma-aplicacao-angular-no-github-pages-usando-o-travis-ci">blog</a> in Portuguese.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Publish an HTML Website on Netlify or GitHub Pages ]]>
                </title>
                <description>
                    <![CDATA[ By Vasyl Lagutin You have finished creating your HTML website and you're feeling proud of your hard work. But there is one thing that is still missing: you have no idea how to publish your website. In this tutorial, you will learn how to publish an H... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/publish-your-website-netlify-github/</link>
                <guid isPermaLink="false">66d45e06182810487e0ce133</guid>
                
                    <category>
                        <![CDATA[ github pages ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Netlify ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 28 Sep 2021 17:36:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/09/How-to-publish-an-HTML-website--3-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Vasyl Lagutin</p>
<p>You have finished creating your HTML website and you're feeling proud of your hard work. But there is one thing that is still missing: you have no idea how to publish your website.</p>
<p>In this tutorial, you will learn how to publish an HTML website using two popular platforms – <strong>Netlify</strong> and <strong>GitHub</strong>.</p>
<p>Before we start, make sure that you have a <a target="_blank" href="https://github.com">GitHub account</a> because you will need to host your repository (your source code) on GitHub. Without it, you won't be able to publish your HTML website following this tutorial.</p>
<h2 id="heading-how-to-publish-a-website-on-netlify">How to Publish a Website on Netlify</h2>
<p>The first method we're going to explore is how to publish your website on <a target="_blank" href="https://www.netlify.com/">Netlify</a>.</p>
<p>Netlify is a platform for hosting websites. It is easy to host sites on Netlify as you don't need to configure it manually – and best of all, it's free. If you haven't signed up for an account, now is a good time to do so.</p>
<p>Here's the step-by-step process of publishing your website on Netlify:</p>
<h3 id="heading-step-1-add-your-new-site">Step 1: Add your new site</h3>
<p>Once you've logged in, it will take you to a home dashboard. Click the <strong>New site from git</strong> button to add your new website to Netlify.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/netlify_1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-2-link-to-your-github">Step 2: Link to your GitHub</h3>
<p>When you click the <strong>New site from git</strong> button, it will take you to the "Create a new site" page. Make sure that you push your repository on GitHub so that Netlify can link to your GitHub account.</p>
<p>Click the <strong>GitHub</strong> button as shown in the screenshot below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/netlify_2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-3-authorize-netlify">Step 3: Authorize Netlify</h3>
<p>Next, click the <strong>Authorize Netlify by Netlify</strong> button. This permission is needed so that both Netlify and GitHub can connect.</p>
<h3 id="heading-step-4-select-your-repository">Step 4: Select your repository</h3>
<p>Once you grant permission to Netlify, you can see a list of all your repositories. Select your website to publish. You can find it by either scrolling down the list or using the search bar to narrow down the list.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/netlify_4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-5-configure-your-settings">Step 5: Configure your settings</h3>
<p>After selecting your website, you will be prompted to configure the settings for deploying the website. Since your website is simply a static one, there's not much to do here. Just click <strong>Deploy site</strong> to continue.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/netlify_5-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-6-publish-your-website">Step 6: Publish your website</h3>
<p>Your website is now ready to publish! Netlify will do the rest of the work for you, and it will only take a minute or so to complete the process.</p>
<p>Now you are done! Your new website is published, and you can view it by clicking the green link.</p>
<p>Right now, your URL looks random, but you can edit it by clicking the <strong>Site settings</strong> button and then the <strong>Change site name</strong> button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/netlify_6-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/netlify_7.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Congratulation on publishing your first new website! Now we'll learn how to publish a website with GitHub.</p>
<h2 id="heading-how-to-publish-a-website-on-github">How to Publish a Website on GitHub</h2>
<p>The second method we'll look at uses GitHub to publish your site. GitHub is a platform for storing, tracking, and managing project source code. It is also where you can publish your HTML website – and like Netlify, it is free to host here.</p>
<p>Here's the step-by-step process of publishing your website on GitHub:</p>
<blockquote>
<p>Note: You can only publish your website on GitHub if you set the repository's visibility to public. If you want to deploy a website while it is private, upgrade your account to Pro or use Netlify to host there instead.</p>
</blockquote>
<h3 id="heading-step-1-go-to-your-websites-repository">Step 1: Go to your website's repository</h3>
<p>After you've logged in, go to the repository on the left sidebar and select the one you want to publish.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/Github_1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-2-select-the-settings">Step 2: Select the settings</h3>
<p>In your repository, click the <strong>Settings</strong> link, and it will take you to the repository's settings page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/Github_2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-3-go-to-github-pages">Step 3: Go to GitHub Pages</h3>
<p>When you're in a repository's settings, scroll down a bit until you see the <strong>Pages</strong> link on the left sidebar. Click it, and it will lead you to GitHub Pages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/Github_3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-4-select-the-branch">Step 4: Select the branch</h3>
<p>In the source section, click the dropdown and select the master branch and save it. Depending on how you name it, it can be <strong>master</strong> or <strong>main</strong>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/Github_4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-5-all-done">Step 5: All done</h3>
<p>And you are done! Your website will be published, and it will take only a minute or so to complete the process. Refresh the page, and you will see a link to your newly published website.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/Github_5.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope you've found this tutorial helpful. You have learned how to publish your HTML website with Netlify and GitHub. Now you can go ahead and show the world of your incredible work.</p>
<p>If you're looking to learn more about modern web-development, I invite you to join my <a target="_blank" href="https://js.coderslang.com">Full-Stack JavaScript Course</a> or <a target="_blank" href="https://learn.coderslang.com">read more articles about JS, HTML and CSS at my programming blog.</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Deploy a Routed React App to GitHub Pages ]]>
                </title>
                <description>
                    <![CDATA[ When we build projects, we want to showcase them online. Instead of buying a domain and taking the time to configure it, it's easier just to host it using GitHub Pages.  A project that just uses JavaScript, HTML and CSS is simple to host on GitHub Pa... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/deploy-a-react-app-to-github-pages/</link>
                <guid isPermaLink="false">66ba4fe98e44e0cdf128124a</guid>
                
                    <category>
                        <![CDATA[ github pages ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react router ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tomer ]]>
                </dc:creator>
                <pubDate>Mon, 22 Feb 2021 22:53:34 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/602aaa1e0a2838549dcc5c67.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When we build projects, we want to showcase them online. Instead of buying a domain and taking the time to configure it, it's easier just to host it using <a target="_blank" href="https://pages.github.com/">GitHub Pages</a>. </p>
<p>A project that just uses JavaScript, HTML and CSS is simple to host on GitHub Pages. Projects that are built in React, Vue or Angular require some configurations, though. This gives anyone who visits your application online the same experience you have when you build the application locally.</p>
<p>In this article, I'll show you how to create a simple React application that uses routing and then we'll learn how to upload it to GitHub Pages. We will give special attention to the routing part since it is important to understand and implement.</p>
<blockquote>
<p>⚠️ This article assumes you have some knowledge of React and Git.</p>
</blockquote>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>You need to have Node, yarn and npm installed on your machine. To check if they are installed, open up a terminal window and type the following:</p>
<pre><code class="lang-bash">npm -v
yarn -v
node -v
</code></pre>
<p>If these commands print out a version number in the terminal, you are good to go. If not, you need to go ahead and install what is missing.</p>
<ul>
<li><a target="_blank" href="https://nodejs.org/en/download/">Node</a> (contains npm)</li>
<li><a target="_blank" href="https://classic.yarnpkg.com/en/docs/install/#windows-stable">Yarn</a></li>
</ul>
<p>We will also need to create a repository on GitHub. Head over to your account and create a new repository. Choose whichever name you deem fit for this project, but I will go with <strong>starter-project</strong> for the rest of this article.</p>
<p>To create our project, we will be using <strong>create-react-app</strong>. It is a package that lets you create a single page application with ease. To create a project, you need to type the following in the terminal:</p>
<pre><code class="lang-bash">npx create-react-app starter-project
</code></pre>
<p>Once the operation finishes, you will have a boilerplate React project, ready to go. To see if it works properly, head into the directory of the project (in our example it would be starter-project) and run the command:</p>
<pre><code class="lang-bash">yarn start
</code></pre>
<p>If everything runs properly, you will see a message in the terminal that says that your application is running on a local server at this address: <strong>http://localhost:3000</strong></p>
<p>If you head over there in your browser, you will see this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/IB8uRE3cjN.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-deploy-your-project-to-github">How to Deploy Your Project to GitHub</h2>
<p>You may have noticed that we have not created any repository in GitHub. So before we move on, we must have our project uploaded there. Head over to your GitHub account and create a repository with the same name as the React project. </p>
<blockquote>
<p>☝️ Make sure to mark your repository as public. If you mark it as private, you won't be able to use GitHub Pages.</p>
</blockquote>
<p>We are going to add this repository as a remote to our project. To do that, in the terminal, type:</p>
<pre><code class="lang-bash">git remote add &lt;name-of-remote&gt; &lt;url-of-repository&gt;
</code></pre>
<p>So, in our case, the command looks like this:</p>
<pre><code class="lang-bash">git remote add origin https://github.com/TomerPacific/starter-project
</code></pre>
<blockquote>
<p>It's important to call the remote <strong><em>origin</em></strong> as it will be used in our deploy process.</p>
</blockquote>
<p>After executing the command above, we can't push our code yet. First, we need to configure an upstream branch and set the remote as origin.</p>
<pre><code class="lang-bash"> git push --set-upstream origin master
</code></pre>
<p>Now, we can push all our project's files to our repository.</p>
<p>In order for us to be able to upload our built application to GitHub Pages, we first need to install the <a target="_blank" href="https://www.npmjs.com/package/gh-pages">gh-pages package</a>.</p>
<pre><code class="lang-bash">yarn add gh-pages
</code></pre>
<p>This package will help us to deploy our code to the gh-pages branch which will be used to host our application on GitHub Pages. </p>
<p>To allow us to use the gh-pages package properly, we need to add two keys to our scripts value in the package.json file:</p>
<pre><code class="lang-package.json">"scripts": {
    "start": "react-scripts start",
    "predeploy": "npm run build", &lt;----------- #1
    "deploy": "gh-pages -d build", &lt;---------- #2
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
</code></pre>
<p>Next, we need to modify our package.json file by adding the <strong>homepage</strong> field. This field is used by React to figure out the root URL in the built HTML file. In it, we will put the URL of our GitHub repository.</p>
<pre><code class="lang-package.json">{
  "name": "starter-project",
  "homepage": "https://tomerpacific.github.io/starter-project/", &lt;----
  "version": "0.1.0",
  /....
}
</code></pre>
<p>To deploy our application, type the following in the terminal:</p>
<pre><code class="lang-bash">npm run deploy
</code></pre>
<p>Running the command above takes care of building your application and pushing it to a branch called gh-pages, which GitHub uses to link with GitHub Pages.</p>
<blockquote>
<p>🚧 If you did not name your remote <strong><em>origin</em></strong>, you will get an error during this phase stating that: <strong>Failed to get remote.origin.url (task must either be run in a git repository with a configured origin remote or must be configured with the "repo" option)</strong>. </p>
</blockquote>
<p>You will know that the process was successful if at the end of it you see the word <strong>Published</strong>. We can now head to our GitHub repository under Settings and scroll down to the GitHub Pages section.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/chrome_egdTtIso1X.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you see a message similar to the one above, it means your application is now hosted successfully on GitHub Pages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-308.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@noahglynn?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Noah Glynn / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<h2 id="heading-routing-in-react">Routing in React</h2>
<p>So far - so good:</p>
<ol>
<li>We have a basic React application that is hosted on GitHub Pages</li>
<li>We also have a streamlined process to deploy it when we want to make changes</li>
</ol>
<p>But since the purpose of this article is to show a more complex application than the one we initially created, we will be discussing routing. </p>
<p>One component that is missing from out application is navigation. Our application won't just be one page, it will probably have many pages. So, how will users be able to navigate between them?</p>
<p>Routing is the practice of selecting a path for traffic in a network. Or in more basic terms, what happens when you click on a link inside of a webpage and where you get redirected. </p>
<p>React is a library, and it does not contain everything you need for your application out of the box (in our case, routing). Therefore, we will need to install <a target="_blank" href="https://reactrouter.com/web/guides/quick-start">react router</a>. </p>
<p>React router has different components for web applications and for native ones. Since we are building a web application, we will be using <strong>react-router-dom</strong>.</p>
<pre><code class="lang-bash">yarn add react-router-dom
</code></pre>
<p>To make use of routing in our application, let's create a navigation element which will be visible at the top of the application. We will be adding this inside our App.js file and replacing the current HTML markup that is there.</p>
<pre><code class="lang-html"> <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"navigation"</span>&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
                 <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/"</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
             <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
                 <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/about"</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
             <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
                 <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/contact"</span>&gt;</span>Contact<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
             <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
         <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Usually, in a non React project, we would put a relative path to our HTML pages for each section. That way, the browser knows where to load the data from. </p>
<p>But in our project, we won't have different HTML pages for each section. We will just load a different component. The markup that used to be inside of App.js will now be found inside of a component called Home.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> logo <span class="hljs-keyword">from</span> <span class="hljs-string">'./logo.svg'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Home</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{logo}</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-logo"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"logo"</span> /&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
                    Edit <span class="hljs-tag">&lt;<span class="hljs-name">code</span>&gt;</span>src/App.js<span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span> and save to reload.
                <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">a</span>
                    <span class="hljs-attr">className</span>=<span class="hljs-string">"App-link"</span>
                    <span class="hljs-attr">href</span>=<span class="hljs-string">"https://reactjs.org"</span>
                    <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span>
                    <span class="hljs-attr">rel</span>=<span class="hljs-string">"noopener noreferrer"</span>
                &gt;</span>
                    Learn React
                <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

        );
    }

}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Home;
</code></pre>
<p>As we have created three sections in our navgiation and taken care of the home section, let's give another example with the <strong>About</strong> section.</p>
<p>We'll create a new file called <strong>About.jsx</strong> that will hold our template and code for the about section.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> divStyle = {
    <span class="hljs-attr">color</span>:<span class="hljs-string">'white'</span>
};

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">About</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{

    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{divStyle}</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>About Page<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This section contains information about...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        )
    }
}



<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> About;
</code></pre>
<p>You may be asking yourself, how will the application know to redirect the user once they click on the about link? For that we will use a component called <strong>Route</strong>. </p>
<p>The Route is one of the most important components in react-router because it lets you render different component based on the path of the URL. For our project, we will use the code below inside of App.js just below the navigation markup.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">Switch</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">exact</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Home</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/about"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">About</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">Switch</span>&gt;</span>
</code></pre>
<p>You can see that we created two routes for home and about. The Switch component lets us group route components together and it will only match one of them.</p>
<p>Our combined App.js file looks like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { Route, Switch, Link } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-router-dom"</span>;
<span class="hljs-keyword">import</span> About <span class="hljs-keyword">from</span> <span class="hljs-string">'./About'</span>;
<span class="hljs-keyword">import</span> Home <span class="hljs-keyword">from</span> <span class="hljs-string">'./Home'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  render() {
      <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"navigation"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/"</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/about"</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/contact"</span>&gt;</span>Contact<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Switch</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">exact</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">Home</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/about"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">About</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">Switch</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
            );
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>One last thing we should do is wrap our entire project in a Router component. We need to do this because it enables us to use routing in our application. We will be using the BrowserRouter component as it uses HTML5's history API.</p>
<pre><code class="lang-html">ReactDOM.render(
  <span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">BrowserRouter</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">BrowserRouter</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span>,
  document.getElementById('root')
);
</code></pre>
<p>If we run things locally, everything seems to work. Let's deploy our augmented project to GitHub Pages and see what the result is.</p>
<h2 id="heading-how-to-handle-routing-using-hashrouter">How to Handle Routing Using HashRouter</h2>
<p>At first glance, everything seems to be working fine. But when you try refreshing the page or navigating through the browser itself, you'll keep getting 404 errors. </p>
<p>Why does this happen? Because GitHub Pages does not support browser history like your browser does. In our case, the route <strong>https://tomerpacific.github.io/starter-project/about</strong> doesn't help GitHub Pages understand where to point the user (since it is a frontend route). </p>
<p>To overcome this problem, we need to use a Hash Router instead of a Browser Router in our application. This type of router uses the hash portion of the URL to keep the UI in sync with the URL.</p>
<pre><code class="lang-html">ReactDOM.render(
  <span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">HashRouter</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">HashRouter</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span>,
  document.getElementById('root')
);
</code></pre>
<p>You can read more about this <a target="_blank" href="https://create-react-app.dev/docs/deployment/#github-pages-https-pagesgithubcom">here</a>.</p>
<p>Deploy your application again and you'll be satisfied with the result. No more 404 errors.</p>
<p>This article was inspired by working on a project of mine. You can view it below:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://tomerpacific.github.io/julOnSaleReact/">https://tomerpacific.github.io/julOnSaleReact/</a></div>
<p>And you can see the source code here:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/TomerPacific/julOnSaleReact">https://github.com/TomerPacific/julOnSaleReact</a></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Publish a no-code website in 10 minutes ]]>
                </title>
                <description>
                    <![CDATA[ In this article, I'll introduce a no-code, no-software and no-cost solution to publishing sophisticated web sites managed by non-technical people. The full codebase is on GitHub here. Sir Issac Newton discovered the law of gravity when practicing “so... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/publish-a-no-code-website-in-10-minutes/</link>
                <guid isPermaLink="false">66d4604ec7632f8bfbf1e459</guid>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub Actions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ github pages ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Hugo ]]>
                    </category>
                
                    <category>
                        <![CDATA[ No Code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Static Site Generators ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sat, 28 Mar 2020 20:59:47 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/03/igor-miske-Px3iBXV-4TU-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, I'll introduce a no-code, no-software and no-cost solution to publishing sophisticated web sites managed by non-technical people. The full codebase is <a target="_blank" href="https://github.com/second-state/hugo-website">on GitHub here</a>.</p>
<p>Sir Issac Newton discovered the law of gravity when practicing “social distancing” during the Plague. What will YOU do? One silver lining of quarantine is that all this free time brings out the entrepreneur spirit and creativity in us.</p>
<p>However, especially because of the quarantine, now more than ever, any new idea or project must have a web site. Traditional CMS solutions like Wordpress, Squarespace, or Wix are difficult to use, look dated, are expensive, or all of the above!</p>
<p>We wanted to create a web site that has a sophisticated look and feel, yet is easy to customize. A non-technical person should be able to edit the source files and see the changes appear on the live web site in a few minutes. Ideally, it should also be free (forever free, not just free-for-now), and can scale to handle millions of visitors if it becomes popular.</p>
<p>Is this possible?</p>
<p>In this short article, I will walk you through a solution based on the Hugo framework, GitHub Pages, and GitHub Actions. You can get up and running with your shiny new website by the end of this article.</p>
<blockquote>
<p>It is so easy that my 9-year-old son did it. He now manages a web site for his fictional country called <a target="_blank" href="https://www.arenztopia.com/">Arenztopia</a>. Check out the <a target="_blank" href="https://medium.com/@michaelyuan_88928/welcome-to-arenztopia-95cc85253163">back story</a>.</p>
</blockquote>
<h2 id="heading-tldr">TL;DR</h2>
<p>If you just want to get started with a working web site as soon as possible, first make sure that you have a free GitHub account.</p>
<p>Go to <a target="_blank" href="https://github.com/second-state/hugo-website">this GitHub repository</a>, and click on the “Fork” button on the top right, and <strong>fork</strong> it to your own account.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_edHfJdOu6Ppjiyd-M4tMJQ.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Go to your forked repository, and click on the Actions tab. You will see a message like the one in the picture below. <strong>Click on</strong> the “I understand my workflows …” button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_nCrYAyGhCmLeFC2PMbUBEA.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Go to the Settings tab of your repository, and then scroll down to GitHub Pages. <strong>Re-select</strong> the <code>gh-pages</code> from the dropdown for the web site to build.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_K4qXL2CN2rtMonI4dXRWnA.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Go to the Code tab of the repository, open the <code>config.toml</code> file, and edit it. <strong>Change</strong> its <code>title</code> attribute to something else, and click on the “Commit changes” button at the bottom. We need this step to trigger the workflow at the new repository.</p>
<p>Wait a few minutes, go to the “published at” web address at GitHub Pages and you will see the template web site.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_WRQaxyvCqagRMfsN6T1B_A.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next, you can customize the site by editing the <code>config.toml</code> file and the files in the <code>content</code> folder. Go to the “Add your own content” section at the end of this article to see how. You can check out <a target="_blank" href="https://github.com/budparr/gohugo-theme-ananke#getting-started">the instructions for the Ananke theme here</a>.</p>
<p>That’s it for the quick start! In the next several sections, I will explain in more detail the concepts and processes.</p>
<h2 id="heading-hugo-basics">Hugo basics</h2>
<p>Older generation CMS solutions like Wordpress are too difficult to adapt to new web site designs, and commercially hosted solutions like SquareSpace are too expensive and not flexible enough. Static web site generators like Hugo offer a good balance among features, flexibility, and ease of authoring.</p>
<ul>
<li><p>Hugo web sites can be customized and modified through configuration files.</p>
</li>
<li><p>New pages and content sections can be written in markdown instead of HTML. That makes content authoring much easier.</p>
</li>
<li><p>There are many modern design themes to choose from.</p>
</li>
<li><p>The output of Hugo is a static HTML web site that can be deployed on any low-cost hosting provider.</p>
</li>
<li><p>Together with static web site hosting services like GitHub Pages and Netlify, they can offer a completely free solution.</p>
</li>
</ul>
<p>The Hugo software distribution is <a target="_blank" href="https://gohugo.io/getting-started/installing/">available</a> on all major operating systems. You can <a target="_blank" href="https://gohugo.io/getting-started/quick-start/">learn about it here</a>. But, since we will use GitHub Actions to automatically build our Hugo web sites, we do not actually need to install Hugo software here.</p>
<p>Here is how to do it.</p>
<h2 id="heading-create-a-template-website">Create a template website</h2>
<p>First, select a Hugo theme. There are <a target="_blank" href="https://themes.gohugo.io/">many</a>. Some are geared toward web sites with one or more content web pages, while others are optimized for blog-like sites with timestamped posts.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_CjWlyVScCKNkxDIxshwYTQ.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Hugo themes</em></p>
<p>Find one you like, download a zip package or clone a GitHub repo, and unpack the theme into a folder. Let’s assume that the theme distribution is unpacked into a folder called <code>my-theme</code>. The following are commands in a Linux terminal. You could use the Terminal app on Mac or PowerShell on Windows.</p>
<p>Next, create your web site project directory on your computer.</p>
<pre><code class="lang-javascript">$ mkdir -r my-site/themes
</code></pre>
<p>Copy the theme folder into your project.</p>
<pre><code class="lang-javascript">$ cp -r my-theme my-site/themes
</code></pre>
<p>Next, copy the theme’s <code>exampleSite</code> to the project’s top-level directory.</p>
<pre><code class="lang-javascript">$ cd my-site
$ cp -r themes/my-theme/exampleSite<span class="hljs-comment">/* ./</span>
</code></pre>
<p>Edit the <code>config.toml</code> in the project root directory <code>my-site/</code> to point to the right theme.</p>
<pre><code class="lang-javascript">baseURL = <span class="hljs-string">"/"</span>themesDir = <span class="hljs-string">"themes"</span>theme = <span class="hljs-string">"my-theme"</span>
</code></pre>
<p>Next, create a GitHub repo called <code>my-site</code>, and push the <code>my-site</code> directory onto its <code>master</code> branch. Here are the steps for <a target="_blank" href="https://help.github.com/en/github/managing-files-in-a-repository/adding-a-file-to-a-repository">uploading files from GitHub’s web UI</a>. Now we are ready to publish the theme example site.</p>
<p>For a Hugo-based system to be useable to a non-developer (or a young developer who has yet to master the command line tools), we must automate the process of building and deploying the static web site.</p>
<h2 id="heading-automate-deployment">Automate deployment</h2>
<p>In the GitHub project, go to Settings and enable GitHub Pages. Select the source to be the <code>gh-pages</code> branch.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_TrbrZti-GFpVBK0HtrezcA.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Settings, GitHub Pages</em></p>
<p>Next, we create a GitHub Actions workflow to run the Hugo command on the source files from <code>master</code> branch, and push the generated HTML files to the <code>gh-pages</code> branch for publication. From the project’s Actions tab, click on the “set up a workflow yourself” button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_b5UuewhfFq2Gfa0vwJ8bqw.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Set up a workflow yourself</em></p>
<p>The workflow is stored in the <code>master</code> branch as <code>.github/workflows/main.yml</code> file. The content of the file is as follows.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">github</span> <span class="hljs-string">pages</span>

<span class="hljs-attr">on:</span>
  <span class="hljs-attr">push:</span>
    <span class="hljs-attr">branches:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">master</span>

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">deploy:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-18.04</span>
    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v1</span>  <span class="hljs-comment"># v2 does not have submodules option now</span>
        <span class="hljs-comment"># with:</span>
        <span class="hljs-comment">#   submodules: true</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Setup</span> <span class="hljs-string">Hugo</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">peaceiris/actions-hugo@v2</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">hugo-version:</span> <span class="hljs-string">'0.62.2'</span>
          <span class="hljs-attr">extended:</span> <span class="hljs-literal">true</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Build</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">hugo</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Deploy</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">peaceiris/actions-gh-pages@v3</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">github_token:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.GITHUB_TOKEN</span> <span class="hljs-string">}}</span>
          <span class="hljs-attr">publish_dir:</span> <span class="hljs-string">./public</span>
</code></pre>
<p>What happens here is that the web site authors and editors will change content and files on the <code>master</code> branch. Whenever new content is pushed to the <code>master</code> branch, the automated GitHub Actions workflow will <a target="_blank" href="https://github.com/peaceiris/actions-hugo/blob/master/README.md">set up the Hugo software</a>, run the <code>hugo</code> command, and turn those files into HTML files for a static web site.</p>
<p>The HTML files are <a target="_blank" href="https://github.com/peaceiris/actions-gh-pages/blob/master/README.md">pushed</a> to the <code>gh-pages</code> branch of the same repository. They will be published on the specified web address by GitHub Pages as configured.</p>
<p>Notice the <code>cname</code> attribute in the last line. That is the <a target="_blank" href="https://help.github.com/en/github/working-with-github-pages/configuring-a-custom-domain-for-your-github-pages-site">custom domain name</a> we set up with GitHub Pages. If you do not have a custom domain name, just remove this line, and you can access your web site at the domain provided by GitHub Pages.</p>
<p>Now go to the web site, and you should see the theme’s default web page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_fkJkt7YXYEZX96Qv3v5u8A.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The HugoSerif template for one of our web sites.</em></p>
<h2 id="heading-add-your-own-content">Add your own content</h2>
<p>To change the default theme web site to your own content, you just need to change the files on the <code>master</code> branch. Please refer to the <a target="_blank" href="https://gohugo.io/content-management/organization/">documentation</a> of your selected theme. In general, Hugo templates work like this:</p>
<ul>
<li><p>The web pages are authored in markdown format and the <code>md</code> files are in the <code>content</code> folder.</p>
</li>
<li><p>Each <code>md</code> file has a header section with properties such as the page’s menu placement, priority, timestamp, excerpt, etc.</p>
</li>
<li><p>The overall configuration, such as the menu items and properties used by multiple pages, are stored in the <code>data</code> folder.</p>
</li>
<li><p>Static content such as raw HTML files, JavaScript files, and image files can be placed in the <code>static</code> folder.</p>
</li>
</ul>
<p>In particular, here is how you customize the Ananke theme that comes with our template:</p>
<ul>
<li><p>The <a target="_blank" href="https://github.com/second-state/hugo-website/blob/master/config.toml">config.toml</a> file allows you to configure the website title, social icons on all pages, and the big featured image on the home page.</p>
</li>
<li><p>All images should be uploaded to the <a target="_blank" href="https://github.com/second-state/hugo-website/tree/master/static/images">static/images</a> folder.</p>
</li>
<li><p>The <a target="_blank" href="https://github.com/second-state/hugo-website/blob/master/content/_index.md">content/_index.md</a> file contains the text for the home page.</p>
</li>
<li><p>To add pages to the site, you can just create <a target="_blank" href="https://guides.github.com/features/mastering-markdown/">markdown</a> files in the <a target="_blank" href="https://github.com/second-state/hugo-website/tree/master/content">content</a> folder. An example is the <a target="_blank" href="https://github.com/second-state/hugo-website/blob/master/content/contact.md">contact.md</a> file. Notice that at the top of the file, there are attributes to control whether this page should be on the website menu.</p>
</li>
<li><p>To add articles to the site, you can create markdown files in the <a target="_blank" href="https://github.com/second-state/hugo-website/tree/master/content/post">content/post</a> folder. Those are blog-like content articles that have dates and titles at the top. The most recent two articles will show up on the home page.</p>
</li>
</ul>
<p>If you are interested in learning more and see how we did it, you can watch our progress at</p>
<ul>
<li><p>The Country of Arenztopia [<a target="_blank" href="https://github.com/juntao/arenztopia">GitHub</a>] [<a target="_blank" href="https://www.arenztopia.com/">Web site</a>]</p>
</li>
<li><p>Second State blog [<a target="_blank" href="https://github.com/second-state/blog">GitHub</a>] [<a target="_blank" href="https://blog.secondstate.io/categories/en/">Web site</a>]</p>
</li>
</ul>
<p>Good luck and stay healthy!</p>
<h2 id="heading-about-the-author">About the author</h2>
<p>Dr. Michael Yuan is the <a target="_blank" href="http://www.michaelyuan.com/">author of 5 books</a> on software engineering. His latest book <a target="_blank" href="https://www.buildingblockchainapps.com/">Building Blockchain Apps</a> was published by Addison-Wesley in Dec 2019. Dr. Yuan is the co-founder of <a target="_blank" href="https://www.secondstate.io/">Second State</a>, a VC-funded startup that brings WebAssembly and Rust technologies to <a target="_blank" href="https://www.secondstate.io/articles/why-webassembly-server/">cloud</a>, <a target="_blank" href="https://docs.secondstate.io/">blockchain</a>, and <a target="_blank" href="https://github.com/second-state/rust-wasm-ai-demo/blob/master/README.md">AI</a> applications. It enables developers to deploy fast, safe, portable, and serverless <a target="_blank" href="https://www.secondstate.io/articles/getting-started-with-rust-function/">Rust functions on Node.js</a>.</p>
<div class="embed-wrapper"><iframe src="https://webassemblytoday.substack.com/embed" width="480" height="320" style="border:1px solid #EEE;background:white" title="Embedded content" loading="lazy"></iframe></div>

<p>Prior to Second State, Dr. Yuan was a long time open source contributor at Red Hat, JBoss, and Mozilla. Outside of software, Dr. Yuan is a Principal Investigator at the National Institutes of Health, with multiple research awards on cancer and public health research. He holds a PhD in astrophysics from the University of Texas at Austin.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to create a free static site with GitHub Pages in 10 minutes ]]>
                </title>
                <description>
                    <![CDATA[ By Travis Fantina Static sites have become all the rage, and with good reason – they are blazingly fast and, with an ever growing number of supported hosting services, pretty easy to set up.  I'm not going to go into all the who, what, when, where or... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-a-free-static-site-with-github-pages-in-10-minutes/</link>
                <guid isPermaLink="false">66d852b2fabb13edf118fa46</guid>
                
                    <category>
                        <![CDATA[ github pages ]]>
                    </category>
                
                    <category>
                        <![CDATA[ jekyll ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 15 Nov 2019 21:45:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9f4a740569d1a4ca41d4.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Travis Fantina</p>
<p>Static sites have become all the rage, and with good reason – they are blazingly fast and, with an ever growing number of supported hosting services, pretty easy to set up. </p>
<p>I'm not going to go into all the who, what, when, where or why of static sites here. I'm assuming that you have at least a vague idea of what they are <em>or</em> just want to create your own site and don't care about the other details. Either way this post is for you.</p>
<p>First, I want you to know I'm writing this for as broad an audience as possible; you don't need any programming knowledge to follow along, but some familiarity with the command line and Git will help out a lot.</p>
<h2 id="heading-so-how-can-you-create-a-static-site-with-github-in-10-minutes">So how can you create a static site with GitHub in 10 minutes?</h2>
<p>We will be working with two specific tools: GitHub Pages, which is specifically designed to serve static content, and a static content generator called Jekyll.</p>
<p>Jekyll is a Ruby gem for creating static sites easily, so you will need to have Ruby installed on your computer if you want to use Jekyll. If you have OSX you most likely already have a version of Ruby (although you may need to update it). If you don’t, or are on a Windows computer, you can learn more about installing it here: <a target="_blank" href="https://www.ruby-lang.org/en/documentation/installation/">Installing Ruby</a>.</p>
<p>With that out of the way, open up a new terminal widow and type <code>gem install bundler jekyll</code>. This will install Bundler (a Ruby package management tool) and Jekyll. </p>
<p>Once those gems (Ruby packages) have installed, type <code>Jekyll new my-static-site</code> (name it whatever you want) which will run Jekyll's generator to create your project in a new directory. After your site is created, hop into your newly created site directory by typing <code>cd my-static-site</code> (or <code>cd</code> whatever you called you project).</p>
<p>Open your project in a text editor and you will see several files and folders Jekyll created for you. Right now you only need to concern yourself with the Gemfile (not Gemfile.lock). The Gemfile is a Ruby file that manages all associated Ruby packages needed to run a project.</p>
<p>The file will contain a line with the Jekyll version, comment it out:</p>
<pre><code class="lang-ruby"><span class="hljs-comment">#gem "jekyll", "~&gt; 4.0.0"</span>
</code></pre>
<p>Then add this line:</p>
<pre><code class="lang-ruby">gem <span class="hljs-string">"github-pages"</span>, <span class="hljs-symbol">group:</span> <span class="hljs-symbol">:jekyll_plugins</span>
</code></pre>
<p>There can be a lot of gotchas when you install the GitHub Pages gem – sometimes the gems it depends on are out of date or the gems you have locally installed are <em>too</em> modern for GitHub Pages. </p>
<p>I have found that this can make it difficult to build and test my Jekyll site locally. It may be easiest just to test your site locally and save building it until you are ready to deploy. However, at the time of this writing you can can specify these dependency versions in your Gemfile and Jekyll will work both locally and with GitHub Pages:</p>
<pre><code class="lang-ruby">gem <span class="hljs-string">"jekyll"</span>, <span class="hljs-string">"~&gt; 3.8.5"</span>
gem <span class="hljs-string">"github-pages"</span>,<span class="hljs-string">"~&gt; 202"</span> , <span class="hljs-symbol">group:</span> <span class="hljs-symbol">:jekyll_plugins</span>
group <span class="hljs-symbol">:jekyll_plugins</span> <span class="hljs-keyword">do</span>
  gem <span class="hljs-string">"jekyll-feed"</span>, <span class="hljs-string">"~&gt; 0.11.0"</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>Thanks to <a target="_blank" href="https://stackoverflow.com/users/6885157/alex-waibel">Alex Waibel</a> on <a target="_blank" href="https://stackoverflow.com/questions/58598084/how-does-one-downgrade-jekyll-to-work-with-github-pages">StackOverflow</a> for that most recent configuration.</p>
<p>To see your site in action, run <code>bundle exec Jekyll serve</code> in your command line. This will start a server and you can see your site by typing "localhost:4000" into the URL bar of a browser.</p>
<p>Voila! You have created a static site with Jekyll and you are in the project directory. You are about 50% done.</p>
<h2 id="heading-lets-get-this-online">Lets get this online</h2>
<p>Go to GitHub.com and sign up, or if you already have an account, select the “new” button and create a repository. It’s important that you name your repository after the link that your GitHub Pages account will be serving, which is your_username.github.io. For example my GitHub username is tfantina and my blog is <a target="_blank" href="https://tfantina.github.io">tfantina.github.io</a>, so my GitHub repo is named: "tfantina.github.io".</p>
<p>Back in your terminal window, push your Jekyll site from your computer up to GitHub by running the following commands:</p>
<pre><code class="lang-shell">git init
git remote add origin git@github.com:&lt;your_github_username&gt;/&lt;your_github_repo_name&gt;.git
git commit -am “Setting up Jekyll!”
git push -u origin master
</code></pre>
<p>(When substituting your username and project name you don't need the opening and closing &lt;&gt;).</p>
<p>Once your changes have been pushed to your repository you should have a working static site. This is because your're using the GitHub Pages gem and named your repository in such a way that GitHub understands you want to serve it with GitHub Pages. </p>
<p>You can confirm this either by visiting your site or by going into the settings tab on GitHub and scrolling to the pages section. You should see a green box showing where your site has been published:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/DFAC66CE-C182-4ECA-9379-87843C730645.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You will also note that you can easily change your theme from in here as well. GitHub provides a few default themes for Jekyll, but of course you can also make your own.<br>If your site says it’s published but looks blank, you may need to do a hard refresh or try looking at your site in a private window. This may seem obvious, but it gets me almost every time I set up a new Jekyll instance.</p>
<p>If everything went according to plan your site should look something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/65F58F30-3000-44E5-96CF-DCC1CFEDF953.png" alt="Image" width="600" height="400" loading="lazy"></p>
<hr>
<p>There you go – in just a few minutes you have created and deployed a static website with GitHub pages. But you probably want to be able to put some content on your page. </p>
<p>I promised this would only take ten minutes, so I won’t dive into all the details of pages, front matter, or the Liquid templating language. That’s a post for another day. But I will share how to create your first post.</p>
<p>Back in your text editor, open the “_posts” folder.  There is already a post welcoming you to your new blog. Create a new markdown file and save it with a name in this format: YEAR-MONTH-DAY-TITLE.markdown (see below):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/B90755E4-B12A-4038-8DD7-AF945E73FE43.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>A Jekyll post contains two sections: front matter, and body.</p>
<p>The front matter gives specific instructions to Jekyll such as what the title of the post is going to be, which layout to use, and when the post was written. </p>
<p>Front matter is highly customizable. For example, I wanted my posts to have hero images, so I created a <code>lead_image</code> tag and placed some syntax in my layout to specifically check for lead images in each post’s front matter. The Liquid templating language makes it easy to pull content from front matter into your theme.</p>
<p>There's a lot more you can do with front matter, but let's start off with a generic example.</p>
<p>The default front matter looks like this:</p>
<pre><code class="lang-markdown">—
layout: post 
title:  "Welcome to Jekyll!"
date:   2019-11-09 18:07:11 -0600
categories: jekyll update
—
</code></pre>
<ul>
<li>Layout tells Jekyll which layout you want the content to be shown on. You can have multiple layouts for different pages or post types.</li>
<li>The post title</li>
<li>The post date</li>
<li>Categories, which are essentially tags. You can add as few or as many as you want separated by spaces.</li>
</ul>
<p>After the front matter your post can be written in <a target="_blank" href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet">Markdown</a>, which gives you lots of flexibility in writing your post content.</p>
<p>Once your post is finished save it and open up your terminal window.</p>
<pre><code class="lang-shell">git commit -am “Publishes first post
git push
</code></pre>
<p>After a minute (and maybe a refresh), you will be able to see your post.</p>
<p>Hopefully, you now have a working static site on GitHub Pages created with Jekyll! If you have any problems or questions please tweet <a target="_blank" href="https://twitter.com/tfantina">@tfantina</a>, or you can shoot me an email at <a target="_blank" href="mailto:contact@travisfantina.com">contact@travisfantina.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to publish GitHub event data with GitHub Actions and Pages ]]>
                </title>
                <description>
                    <![CDATA[ Teams who work on GitHub rely on event data to collaborate.  The data recorded as issues, pull requests, and comments become vital to understanding the project. With the general availability of GitHub Actions, we have a chance to programmatically acc... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/publishing-github-event-data-with-github-actions-and-pages/</link>
                <guid isPermaLink="false">66bd8f70c1ca1df1936e29d9</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub Actions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ github pages ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Victoria Drake ]]>
                </dc:creator>
                <pubDate>Tue, 05 Nov 2019 14:12:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Teams who work on GitHub rely on event data to collaborate.  The data recorded as issues, pull requests, and comments become vital to understanding the project.</p>
<p>With the general availability of GitHub Actions, we have a chance to programmatically access and preserve GitHub event data in our repository. Making the data part of the repository itself is a way of preserving it outside of GitHub. It also gives us the ability to feature the data on a front-facing website, such as with GitHub Pages.</p>
<p>And, if you’re like me, you can turn <a target="_blank" href="https://github.com/victoriadrake/github-guestbook/issues/1">GitHub issue comments</a> into an <a target="_blank" href="https://victoria.dev/github-guestbook/">awesome 90s guestbook page</a>.</p>
<p>No matter the usage, the principle concepts are the same. We can use Actions to access, preserve, and display GitHub event data - with just one workflow file. To illustrate the process, I’ll take you through the <a target="_blank" href="https://github.com/victoriadrake/github-guestbook/blob/master/.github/workflows/publish-comments.yml">workflow code</a> that makes my guestbook shine on.</p>
<p>For an introductory look at GitHub Actions including how workflows are triggered, see <a target="_blank" href="https://victoria.dev/blog/a-lightweight-tool-agnostic-ci/cd-flow-with-github-actions/">A lightweight, tool-agnostic CI/CD flow with GitHub Actions</a>.</p>
<h2 id="heading-accessing-github-event-data">Accessing GitHub event data</h2>
<p>An Action workflow runs in an environment with some default environment variables. A lot of convenient information is available here, including event data. The most complete way to access the event data is using the <code>$GITHUB_EVENT_PATH</code> variable, the path of the file with the complete JSON event payload.</p>
<p>The expanded path looks like <code>/home/runner/work/_temp/_github_workflow/event.json</code> and its data corresponds to its webhook event. You can find the documentation for webhook event data in GitHub REST API <a target="_blank" href="https://developer.github.com/webhooks/#events">Event Types and Payloads</a>. To make the JSON data available in the workflow environment, you can use a tool like <code>jq</code> to parse the event data and put it in an environment variable.</p>
<p>Below, I grab the comment ID from an <a target="_blank" href="https://developer.github.com/v3/activity/events/types/#issuecommentevent">issue comment event</a>:</p>
<pre><code>ID=<span class="hljs-string">"$(jq '.comment.id' $GITHUB_EVENT_PATH)"</span>
</code></pre><p>Most event data is also available via the <a target="_blank" href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#github-context"><code>github.event</code> context variable</a> without needing to parse JSON. The fields are accessed using dot notation, as in the example below where I grab the same comment ID:</p>
<pre><code>ID=${{ github.event.comment.id }}
</code></pre><p>For my guestbook, I want to display entries with the user’s handle, and the date and time. I can capture this event data like so:</p>
<pre><code>AUTHOR=${{ github.event.comment.user.login }}
DATE=${{ github.event.comment.created_at }}
</code></pre><p>Shell variables are handy for accessing data, however, they’re ephemeral. The workflow environment is created anew each run, and even shell variables set in one step do not persist to other steps. To persist the captured data, you have two options: use artifacts, or commit it to the repository.</p>
<h2 id="heading-preserving-event-data-using-artifacts">Preserving event data: using artifacts</h2>
<p>Using artifacts, you can persist data between workflow jobs without committing it to your repository. This is handy when, for example, you wish to transform or incorporate the data before putting it somewhere more permanent. It’s necessary to persist data between workflow jobs because:</p>
<blockquote>
<p>Each job in a workflow runs in a fresh instance of the virtual environment. When the job completes, the runner terminates and deletes the instance of the virtual environment. <em>(<a target="_blank" href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/persisting-workflow-data-using-artifacts">Persisting workflow data using artifacts</a>)</em></p>
</blockquote>
<p>Two actions assist with using artifacts: <code>upload-artifact</code> and <code>download-artifact</code>. You can use these actions to make files available to other jobs in the same workflow. For a full example, see <a target="_blank" href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/persisting-workflow-data-using-artifacts#passing-data-between-jobs-in-a-workflow">passing data between jobs in a workflow</a>.</p>
<p>The <code>upload-artifact</code> action’s <code>action.yml</code> contains an <a target="_blank" href="https://github.com/actions/upload-artifact/blob/master/action.yml">explanation</a> of the keywords. The uploaded files are saved in <code>.zip</code> format. Another job in the same workflow run can use the <code>download-artifact</code> action to utilize the data in another step.</p>
<p>You can also manually download the archive on the workflow run page, under the repository’s Actions tab.</p>
<p>Persisting workflow data between jobs does not make any changes to the repository files, as the artifacts generated live only in the workflow environment. </p>
<p>Personally, being comfortable working in a shell  environment, I see a narrow use case for artifacts, though I’d have been remiss not to mention them. Besides passing data between jobs, they could be useful for creating <code>.zip</code> format archives of, say, test output data. In the case of my guestbook example, I simply ran all  the necessary steps in one job, negating any need for passing data  between jobs.</p>
<h2 id="heading-preserving-event-data-pushing-workflow-files-to-the-repository">Preserving event data: pushing workflow files to the repository</h2>
<p>To preserve data captured in the workflow in the repository itself, it is necessary to add and push this data to the Git repository. You can do this in the workflow by creating new files with the data, or by appending data to existing files, using shell commands.</p>
<h3 id="heading-creating-files-in-the-workflow">Creating files in the workflow</h3>
<p>To work with the repository files in the workflow, use the <a target="_blank" href="https://github.com/actions/checkout"><code>checkout</code> action</a> to first get a copy to work with:</p>
<pre><code>- uses: actions/checkout@master
  <span class="hljs-attr">with</span>:
    fetch-depth: <span class="hljs-number">1</span>
</code></pre><p>To add comments to my guestbook, I turn the event data captured in shell variables into proper files, using substitutions in <a target="_blank" href="https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html">shell parameter expansion</a> to sanitize user input and translate newlines to paragraphs. I wrote previously about <a target="_blank" href="https://victoria.dev/blog/sql-injection-and-xss-what-white-hat-hackers-know-about-trusting-user-input/">why user input should be treated carefully</a>.</p>
<pre><code>- name: Turn comment into file
  <span class="hljs-attr">run</span>: |
    ID=${{ github.event.comment.id }}
    AUTHOR=${{ github.event.comment.user.login }}
    DATE=${{ github.event.comment.created_at }}
    COMMENT=$(echo <span class="hljs-string">"${{ github.event.comment.body }}"</span>)
    NO_TAGS=${COMMENT<span class="hljs-comment">//[&lt;&gt;]/\`}</span>
    FOLDER=comments

    printf <span class="hljs-string">'%b\n'</span> <span class="hljs-string">"&lt;div class=\"comment\"&gt;&lt;p&gt;${AUTHOR} says:&lt;/p&gt;&lt;p&gt;${NO_TAGS//$'\n'/\&lt;\/p\&gt;\&lt;p\&gt;}&lt;/p&gt;&lt;p&gt;${DATE}&lt;/p&gt;&lt;/div&gt;\r\n"</span> &gt; ${FOLDER}/${ID}.html
</code></pre><p>By using <code>printf</code> and directing its output with <code>&gt;</code> to a new file, the event data is transformed into an HTML file, named with the comment ID number, that contains the captured event data. Formatted, it looks like:</p>
<pre><code>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"comment"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>victoriadrake says:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is a comment!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>2019-11-04T00:28:36Z<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
&lt;/div&gt;
</code></pre><p>When working with comments, one effect of naming files using the comment ID is that a new file with the same ID will overwrite the previous. This is handy for a guestbook, as it allows any edits to a comment to replace the original comment file.</p>
<p>If you’re using a static site generator like Hugo, you could build a Markdown format file, stick it in your <code>content/</code> folder, and the regular site build will take care of the rest. </p>
<p>In the case of my simplistic guestbook, I have an extra step to consolidate the  individual comment files into a page. Each time it runs, it overwrites the existing <code>index.html</code> with the <code>header.html</code> portion (<code>&gt;</code>), then finds and appends (<code>&gt;&gt;</code>) all the comment files’ contents in descending order, and lastly appends the <code>footer.html</code> portion to end the page.</p>
<pre><code>- name: Assemble page
  <span class="hljs-attr">run</span>: |
    cat header.html &gt; index.html
    find comments/ -name <span class="hljs-string">"*.html"</span> | sort -r | xargs -I % cat % &gt;&gt; index.html
    cat footer.html &gt;&gt; index.html
</code></pre><h3 id="heading-committing-changes-to-the-repository">Committing changes to the repository</h3>
<p>Since the <code>checkout</code> action is not quite the same as cloning the repository, at time of writing, there are some <a target="_blank" href="https://github.community/t5/GitHub-Actions/Checkout-Action-does-not-create-local-master-and-has-no-options/td-p/31575">issues</a> still to work around. A couple extra steps are necessary to <code>pull</code>, <code>checkout</code>, and successfully <code>push</code> changes back to the <code>master</code> branch, but this is pretty trivially done in the shell.</p>
<p>Below is the step that adds, commits, and pushes changes made by the workflow back to the repository’s <code>master</code> branch.</p>
<pre><code>- name: Push changes to repo
  <span class="hljs-attr">run</span>: |
    REMOTE=https:<span class="hljs-comment">//${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}</span>
    git config user.email <span class="hljs-string">"${{ github.actor }}@users.noreply.github.com"</span>
    git config user.name <span class="hljs-string">"${{ github.actor }}"</span>

    git pull ${REMOTE}
    git checkout master
    git add .
    git status
    git commit -am <span class="hljs-string">"Add new comment"</span>
    git push ${REMOTE} master
</code></pre><p>The remote, in fact, our repository, is specified using the <code>github.repository</code> context variable. For our workflow to be allowed to push to master, we use the <code>secrets.GITHUB_TOKEN</code> variable.</p>
<p>Since the workflow environment is shiny and newborn, we need to configure Git. In the above example, I’ve used the <code>github.actor</code> context variable to input the username of the account initiating the workflow. The email is similarly configured using the <a target="_blank" href="https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/setting-your-commit-email-address#setting-your-commit-email-address-on-github">default <code>noreply</code> GitHub email address</a>.</p>
<h2 id="heading-displaying-event-data">Displaying event data</h2>
<p><em>Nov 6, 2019 correction: GitHub Actions requires a Personal Access Token to trigger a Pages site build.</em></p>
<p>If you're using GitHub Pages with the default <code>secrets.GITHUB_TOKEN</code> variable and without a site generator, pushing changes to the  repository in the workflow will only update the repository files. The  GitHub Pages build will fail with an error, "Your site is having  problems building: Page build failed."</p>
<p>To enable Actions to trigger a Pages site build, you'll need to create a Personal Access Token. This token can be <a target="_blank" href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets">stored as a secret in the repository</a> settings and passed into the workflow in place of the default <code>secrets.GITHUB_TOKEN</code> variable. I wrote more about <a target="_blank" href="https://victoria.dev/blog/a-lightweight-tool-agnostic-ci/cd-flow-with-github-actions/#environment-and-variables">Actions environment and variables in this post</a>.</p>
<p>With the use of a Personal Access Token, a push initiated by the  Actions workflow will also update the Pages site. You can see it for  yourself by <a target="_blank" href="https://github.com/victoriadrake/github-guestbook/issues/1">leaving a comment</a> in my <a target="_blank" href="https://victoria.dev/github-guestbook/">guestbook</a>!  The comment creation event triggers the workflow, which then takes  around 30 seconds to a minute to run and update the guestbook page.</p>
<p>Where a site build is necessary for changes to be published, such as  when using Hugo, an Action can do this too. However, in order to avoid  creating unintended loops, <a target="_blank" href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/events-that-trigger-workflows#about-workflow-events">one Action workflow will not trigger another</a>. Instead, it's extremely convenient to handle the process of <a target="_blank" href="https://victoria.dev/blog/a-portable-makefile-for-continuous-delivery-with-hugo-and-github-pages/">building the site with a Makefile</a>,  which any workflow can then run. Simply add running the Makefile as the  final step in your workflow job, with the repository token where  necessary:</p>
<pre><code>- name: Run Makefile
  <span class="hljs-attr">env</span>:
    TOKEN: ${{ secrets.GITHUB_TOKEN }}
  <span class="hljs-attr">run</span>: make all
</code></pre><p>This ensures that the final step of your workflow builds and deploys the updated site.</p>
<h2 id="heading-no-more-event-data-horizon">No more event data horizon</h2>
<p>GitHub Actions provides a neat way to capture and utilize event data so that it’s not only available within GitHub. The possibilities are only as limited as your imagination! Here are a few ideas for things this lets us create:</p>
<ol>
<li>A public-facing issues board, where customers without GitHub accounts can view and give feedback on project issues.</li>
<li>An automatically-updating RSS feed of new issues, comments, or PRs for any repository.</li>
<li>A comments system for static sites, utilizing GitHub issue comments as an input method.</li>
<li>An awesome 90s guestbook page.</li>
</ol>
<p>Did I mention I made a <a target="_blank" href="https://victoria.dev/github-guestbook/">90s guestbook page</a>? My inner-Geocities-nerd is a little excited.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
