<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bassel Cheaib</title>
    <description>The latest articles on DEV Community by Bassel Cheaib (@bassel).</description>
    <link>https://dev.to/bassel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F168536%2F2c7177ad-a3c6-4851-bcc2-69086e565731.jpg</url>
      <title>DEV Community: Bassel Cheaib</title>
      <link>https://dev.to/bassel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bassel"/>
    <language>en</language>
    <item>
      <title>Add a portfolio to your Ghost blog</title>
      <dc:creator>Bassel Cheaib</dc:creator>
      <pubDate>Sat, 12 Dec 2020 10:41:32 +0000</pubDate>
      <link>https://dev.to/bassel/add-a-portfolio-to-your-ghost-blog-3n00</link>
      <guid>https://dev.to/bassel/add-a-portfolio-to-your-ghost-blog-3n00</guid>
      <description>&lt;p&gt;When building a personal blog, you don't have to re-invent the wheel and implement everything from scratch. Many people tend to use a CMS in order to focus more on the blog's content instead of having to focus on building the barebones of the blog (taxonomies, pagination, SEO, etc) from scratch.&lt;/p&gt;

&lt;p&gt;There are many solutions available like WordPress, Drupal, Ghost, etc. Each one has its own pros and cons, but for me I've always been a fan of &lt;a href="https://ghost.org/" rel="noopener noreferrer"&gt;Ghost&lt;/a&gt; when it comes to managing blog content.&lt;/p&gt;

&lt;p&gt;One special thing about Ghost is that it focuses mainly on content publishing. But does that mean that it can't be used for other types of content? Not at all. Thanks to its flexible routing system, it allows you to also build powerful custom site structures.&lt;/p&gt;

&lt;p&gt;Here's how you can customize the default routes to add your personal portfolio to a ghost blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding collections and channels
&lt;/h2&gt;

&lt;p&gt;In ghost, you can create your own specific channels in order to change the organization of your content and what URLs they live on. It's important to note that &lt;strong&gt;a post can be only in one collection&lt;/strong&gt;. That's why it's necessary to properly setup your filters to insure that.&lt;/p&gt;

&lt;p&gt;But what if you want a post to be accessible from multiple routes? Like for example when you want a project to be displayed on your general portfolio &lt;strong&gt;and&lt;/strong&gt; on a page where you only have mobile projects? Well, that's where channels come to the rescue. A channel is a collection of content matching a specific filter. Unlike collections, they don't influence the post's URL which is why it's possible to have a post present on multiple channels.&lt;/p&gt;

&lt;p&gt;Enough theory for now... Once we see an example in action, you'll have a better idea about the difference between collections and channels.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding the portfolio projects
&lt;/h2&gt;

&lt;p&gt;The first thing to do is to create a tag called "Portfolio" (the name doesn't really matter, so you can choose any other name you want). This will be the primary tag assigned to all of our portfolio projects. Just like with any other post, you can assign as many tags to the project. The important thing is to have the same primary tag for all the projects you add (It's the &lt;em&gt;Portfolio&lt;/em&gt; tag in this case).&lt;/p&gt;

&lt;p&gt;A project is just like any other post, except that it has the tag &lt;em&gt;Portfolio&lt;/em&gt;:&lt;/p&gt;

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

&lt;p&gt;Once you add a couple of projects, you'll notice that they will appear on your home page alongside the other posts. But ideally, we'd want our portfolio to be separate from the blog.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Separating the portfolio from the blog
&lt;/h2&gt;

&lt;p&gt;The first step now is to download your routes file. To do that, go to the &lt;strong&gt;Labs&lt;/strong&gt; section in your dashboard and press on &lt;em&gt;"Download current routes.yaml"&lt;/em&gt; at the very bottom.&lt;/p&gt;

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

&lt;p&gt;By default, your &lt;code&gt;routes.yaml&lt;/code&gt; should look like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;collections&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;/&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/{slug}/&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;index&lt;/span&gt;

&lt;span class="na"&gt;taxonomies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/tag/{slug}/&lt;/span&gt;
  &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/author/{slug}/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we need to do now is to filter out the portfolio items from the home page and move them to their own directory. In addition to that, we'll use the template page of the tag in order to display a header and a small description about the portfolio. The updated &lt;code&gt;routes.yaml&lt;/code&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;collections&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;/&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/{slug}/&lt;/span&gt;
    &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;primary_tag:-portfolio&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;index&lt;/span&gt;
  &lt;span class="na"&gt;/portfolio/&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/portfolio/{slug}/&lt;/span&gt;
    &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;primary_tag:portfolio&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag.portfolio&lt;/span&gt;

&lt;span class="na"&gt;taxonomies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/tag/{slug}/&lt;/span&gt;
  &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/author/{slug}/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what happened here?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;filter&lt;/code&gt; property under home is telling it to get all the posts except the ones that have a primary tag of portfolio (notice the minus sign before portfolio)&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;filter&lt;/code&gt; under &lt;code&gt;/portfolio/&lt;/code&gt; tells it to get only the ones with the primary tag of portfolio.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By using these two filters, we ensure that anything with &lt;em&gt;portfolio&lt;/em&gt; as a primary tag will belong only to the portfolio collection. A few more thing to note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The permalink of the portfolio collection is /portfolio/{slug}/ which means that all the posts that belong to this collection will have a URL of this form&lt;/li&gt;
&lt;li&gt;The template we're using is &lt;code&gt;tag&lt;/code&gt; which tells the theme to use the &lt;code&gt;tag.hbs&lt;/code&gt; template when building the portfolio page. You can even create a custom template and use it for your portfolio page by specifying it here.&lt;/li&gt;
&lt;li&gt;Since the &lt;code&gt;tag&lt;/code&gt; template needs the data of a tag to display properly, we are passing the portfolio tag's data by specifying the &lt;code&gt;data&lt;/code&gt; property of the collection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using channels to create specialized profiles
&lt;/h2&gt;

&lt;p&gt;Let's say you want to show someone all the mobile apps you built previously by sending them the link &lt;code&gt;portfolio/mobile/&lt;/code&gt;. You could follow the same process as before and create that as a collection, but as we mentioned before a post can live in one collection only. Which means that by doing this, they won't appear in your primary portfolio page anymore.&lt;/p&gt;

&lt;p&gt;In cases like that, it's better to use channels. You can think of channels as a set of permanent search results. It allows you to have a filtered slice of content from your site, without modifying the content itself.&lt;/p&gt;

&lt;p&gt;Here's an example of how you can do that inside your &lt;code&gt;routes.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;/portfolio/mobile/&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;controller&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;channel&lt;/span&gt;
    &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag:portfolio+tag:mobile&lt;/span&gt;
  &lt;span class="na"&gt;/portfolio/desktop/&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;controller&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;channel&lt;/span&gt;
    &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag:portfolio+tag:desktop&lt;/span&gt;
  &lt;span class="na"&gt;/portfolio/web/&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;controller&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;channel&lt;/span&gt;
    &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag:portfolio+tag:websites&lt;/span&gt;

&lt;span class="na"&gt;collections&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;/&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/{slug}/&lt;/span&gt;
    &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;primary_tag:-portfolio&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;index&lt;/span&gt;
  &lt;span class="na"&gt;/portfolio/&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/portfolio/{slug}/&lt;/span&gt;
    &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;primary_tag:portfolio&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag.portfolio&lt;/span&gt;

&lt;span class="na"&gt;taxonomies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/tag/{slug}/&lt;/span&gt;
  &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/author/{slug}/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the new modifications are inside &lt;code&gt;routes&lt;/code&gt;. What happens now is that all the posts matching the specific filter you set on a certain route will appear inside that route while still appearing inside their own collection too.&lt;/p&gt;

&lt;p&gt;There are tons of filters you can use; here's an example of the possible combinations you can have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag:x+tag:y&lt;/span&gt; &lt;span class="c1"&gt;# must have both "x" and "y" tags (+ = AND)&lt;/span&gt;
&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag:x,tag:y&lt;/span&gt; &lt;span class="c1"&gt;# can have either "x" or "y" tags (, = OR)&lt;/span&gt;
&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag:-x+tag:y&lt;/span&gt; &lt;span class="c1"&gt;# must have tag "y" but not tag "x" (- = NOT)&lt;/span&gt;
&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag:[x,y,z]&lt;/span&gt; &lt;span class="c1"&gt;# must have either "x", "y", or "z" tags ([] = IN)&lt;/span&gt;
&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag:-[x,y,z]&lt;/span&gt; &lt;span class="c1"&gt;# must not have any one of "x", "y", or "z" tags (-[] = NOT IN)&lt;/span&gt;
&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;author:steve+tag:x&lt;/span&gt; &lt;span class="c1"&gt;# must be written by "steve" and have tag "x"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting the new routes.yaml
&lt;/h2&gt;

&lt;p&gt;By now, we have our updated &lt;code&gt;routes.yaml&lt;/code&gt;, and all we need to do is set it on our website. To do that, you go to the lab section on the dashboard and you go to the same place where you downloaded the initial file. From there, you can press the &lt;em&gt;Upload routes YAML&lt;/em&gt; button and select the updated file to upload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding redirects
&lt;/h2&gt;

&lt;p&gt;One more thing you can do is to set a redirect from &lt;code&gt;/tag/portfolio&lt;/code&gt; to &lt;code&gt;portfolio&lt;/code&gt; directly because they are now the exact same page (same layout, data and content). To do that, download your initial redirects file from the lab. If you haven't worked with it before, it should be an empty file.&lt;/p&gt;

&lt;p&gt;Now add the redirect you want to it. In our case it becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/tag/portfolio/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"/portfolio/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"permanent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then re-upload it like you did for the &lt;code&gt;routes.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;That's all! Thank you for reading and have a nice day!&lt;/p&gt;

</description>
      <category>ghost</category>
    </item>
    <item>
      <title>Hosting your Ghost blog on GitHub pages for free</title>
      <dc:creator>Bassel Cheaib</dc:creator>
      <pubDate>Sat, 12 Dec 2020 10:28:59 +0000</pubDate>
      <link>https://dev.to/bassel/hosting-your-ghost-blog-on-github-pages-for-free-53hl</link>
      <guid>https://dev.to/bassel/hosting-your-ghost-blog-on-github-pages-for-free-53hl</guid>
      <description>&lt;p&gt;&lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;GitHub Pages&lt;/a&gt; is an amazing solution for hosting static websites. By using static site generators (like Jekyll, Hugo, Gatsby and many others) you can easily host your personal blog for free there.&lt;/p&gt;

&lt;p&gt;But what if you're using a CMS like &lt;a href="https://ghost.org/" rel="noopener noreferrer"&gt;Ghost&lt;/a&gt; to manage your blog? Does that mean that you'll end up having to pay in order to host it?&lt;/p&gt;

&lt;p&gt;Well, not necessarily. You can have a local installation of Ghost where you manage everything, then convert it to a static site and publish it for free every time you make changes! Let's get into more details regarding how to do that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Assumptions
&lt;/h2&gt;

&lt;p&gt;Before you continue with this article, you'll need to complete the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Have a running local installation of ghost on your machine. You can do that by following &lt;a href="https://ghost.org/docs/install/local/" rel="noopener noreferrer"&gt;this guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If you're a Windows user, you'll need to have the Windows Subsystem for Linux enabled. &lt;a href="https://www.windowscentral.com/install-windows-subsystem-linux-windows-10" rel="noopener noreferrer"&gt;Here's how you can do it&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Generating the static site
&lt;/h2&gt;

&lt;p&gt;In order to generate the static site, we'll use the &lt;a href="https://github.com/Fried-Chicken/ghost-static-site-generator" rel="noopener noreferrer"&gt;Ghost static site generator&lt;/a&gt;. With Linux and macOS, this tool can be used directly. However, it's more challenging when you're running on a Windows machine.&lt;/p&gt;

&lt;p&gt;The reason for that is that this tool uses &lt;code&gt;wget&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; under the hood. That's where the Windows subsystem for Linux comes to the rescue. If you're not using a windows machine, you can directly skip to step 2.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Prepare the environment (Windows only)
&lt;/h3&gt;

&lt;p&gt;Launch the Linux shell and make sure to install npm inside it. To do that, you can run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;npm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Install the tool globally
&lt;/h3&gt;

&lt;p&gt;You can do that by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; ghost-static-site-generator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For windows users, you can now exit the Linux shell by running the  &lt;code&gt;exit&lt;/code&gt; command.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Generate the site
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create an empty directory of your choice&lt;/li&gt;
&lt;li&gt;Open a terminal in this directory (Windows: press SHIFT + Right Click inside this directory then select "Open Linux shell here")&lt;/li&gt;
&lt;li&gt;Make sure your local ghost installation is running and accessible through the browser. By default it should be running on localhost with the port 2368&lt;/li&gt;
&lt;li&gt;Run the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gssg --url https://username.github.io
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This assumes you'll be pushing the code to your main GitHub site repository named &lt;em&gt;username&lt;/em&gt;.github.io, where &lt;em&gt;username&lt;/em&gt; is your username (or organization name) on GitHub.&lt;/p&gt;

&lt;p&gt;In case you were using a custom URL or even publishing it to other providers like Netlify, change the URL accordingly. The important thing is that it matches the URL where the site will be deployed.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Deploy it online
&lt;/h3&gt;

&lt;p&gt;By now, you should have a folder named &lt;strong&gt;static&lt;/strong&gt; inside the folder you created earlier. This is where the entire static website has been generated. All you have to do is push this code to the repository and wait for it to be deployed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Bonus:&lt;/em&gt;&lt;/strong&gt; if you're using Netlify, you can also just drag and drop this folder into the sites section on &lt;a href="https://app.netlify.com/" rel="noopener noreferrer"&gt;your dashboard&lt;/a&gt; and it will be automatically deployed.&lt;/p&gt;

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

&lt;p&gt;That's all! Whenever you create new content or update anything, all you need to do is repeat steps 3 and 4.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small note:&lt;/strong&gt; There's another possible approach that allows you to make this process even simpler, which is to use Ghost as a headless CMS for a static site generator (Gatsby, Hugo, Next.js, etc). If you'd like to know more about that, you can check the following links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ghost.org/changelog/jamstack/" rel="noopener noreferrer"&gt;Ghost on the JAMstack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gatsbyjs.com/docs/sourcing-from-ghost/" rel="noopener noreferrer"&gt;Using Ghost as a headless CMS for Gatsby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ghost.org/integrations/netlify/" rel="noopener noreferrer"&gt;Add a Netlify webhook for automatic deployments&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ghost</category>
    </item>
  </channel>
</rss>
