<?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: Kinsta</title>
    <description>The latest articles on DEV Community by Kinsta (@kinsta).</description>
    <link>https://dev.to/kinsta</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%2F855128%2F1b7cf0d4-0122-4a2c-bf4d-c8fa90c1c7ed.png</url>
      <title>DEV Community: Kinsta</title>
      <link>https://dev.to/kinsta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kinsta"/>
    <language>en</language>
    <item>
      <title>Jekyll Tutorial: How To Create a Static Website</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Wed, 25 Oct 2023 13:00:00 +0000</pubDate>
      <link>https://dev.to/kinsta/jekyll-tutorial-how-to-create-a-static-website-1cla</link>
      <guid>https://dev.to/kinsta/jekyll-tutorial-how-to-create-a-static-website-1cla</guid>
      <description>&lt;p&gt;Jekyll is a free open-source SSG that is built and runs on the &lt;a href="https://kinsta.com/docs/ruby-on-rails-example-application/" rel="noopener noreferrer"&gt;Ruby&lt;/a&gt; programming language. You don’t need to understand how Ruby works to use Jekyll; you only need to have Ruby installed on your machine.&lt;/p&gt;

&lt;p&gt;Jekyll can be used to build various types of static sites such as a personal blog, portfolio website, and documentation website without needing a database or using a content management system like &lt;a href="https://kinsta.com/blog/wordpress-vs-static-html/" rel="noopener noreferrer"&gt;WordPress&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Install Jekyll&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You first need to install Ruby on your machine before you can proceed to install the Jekyll as stated in the &lt;a href="https://jekyllrb.com/docs/installation/#requirements" rel="noopener noreferrer"&gt;Jekyll documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How To Install Jekyll on macOS&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;By default, Ruby comes preinstalled with macOS, but it’s not recommended you use such a version of Ruby to install Jekyll because it’s old. For example, on Ventura, Apple’s latest operating system, the version of Ruby that comes preinstalled is 2.6.10, of which the latest version is 3.1.3 (as of when this article is written).&lt;/p&gt;

&lt;p&gt;To fix this, you’d need to install Ruby correctly using a version manager such as &lt;a href="https://github.com/postmodern/chruby" rel="noopener noreferrer"&gt;chruby&lt;/a&gt;. You’d need to install &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;Homebrew&lt;/a&gt; on your Mac first using the command below in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the installation is successful, quit and restart Terminal, then check if Homebrew is ready to go by running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew doctor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you get “&lt;strong&gt;Your system is ready to brew”&lt;/strong&gt;, you can now move on to install &lt;code&gt;chruby&lt;/code&gt; and &lt;strong&gt;ruby-install&lt;/strong&gt; with the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;chruby ruby-install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now install ruby’s latest version which is 3.1.3 using the &lt;code&gt;ruby-install&lt;/code&gt; package you just installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ruby-install 3.1.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will take a few minutes. Once it’s successful, configure your shell to automatically use &lt;code&gt;chruby&lt;/code&gt; with the command below:&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;echo&lt;/span&gt; &lt;span class="s2"&gt;"source &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;brew &lt;span class="nt"&gt;--prefix&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/opt/chruby/share/chruby/chruby.sh"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zshrc
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"source &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;brew &lt;span class="nt"&gt;--prefix&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/opt/chruby/share/chruby/auto.sh"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zshrc
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"chruby ruby-3.1.3"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now quit and relaunch your terminal, then check that everything works by running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ruby &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should say &lt;strong&gt;ruby 3.1.3&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You now have Ruby’s latest version installed on your machine. You can now proceed to install the latest Jekyll and bundler gem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;jekyll bundler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;How To Install Jekyll on Windows&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To install Ruby and Jekyll on a Windows machine, you’d use the &lt;a href="https://rubyinstaller.org/" rel="noopener noreferrer"&gt;RubyInstaller&lt;/a&gt;. This can be done by downloading and installing a &lt;strong&gt;Ruby+Devkit&lt;/strong&gt; version from &lt;a href="https://rubyinstaller.org/downloads/" rel="noopener noreferrer"&gt;RubyInstaller Downloads&lt;/a&gt; and using the default options for installation.&lt;/p&gt;

&lt;p&gt;On the last stage of the installation wizard, run the &lt;code&gt;ridk install&lt;/code&gt; step — which is used to install gems. Read more via the &lt;a href="https://github.com/oneclick/rubyinstaller2#using-the-installer-on-a-target-system" rel="noopener noreferrer"&gt;RubyInstaller Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;From the options, choose MSYS2 and MINGW development toolchain. Open a new command prompt window and install Jekyll and Bundler using the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;jekyll bundler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;How To Verify That Jekyll Is Installed Correctly&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To verify that Jekyll is installed correctly on your machine, open your terminal and 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;jekyll &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see the version number, it means that Jekyll is installed and working correctly on your system. You’re now ready to use Jekyll!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How Do You Create a Static Website on Jekyll?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that you have Jekyll installed on your machine, it’s now possible to create a Jekyll static website with one command within a few seconds. Open your terminal and run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jekyll new joels-blog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure you replace “joels-blog” with your preferred site name.&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%2Fuploads%2Farticles%2Flj9ng10atjsivf0tafec.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flj9ng10atjsivf0tafec.jpg" alt="Create a Jekyll static website"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jekyll static website&lt;/p&gt;

&lt;p&gt;Next, navigate to the website folder. You will notice a basic Jekyll site structure that includes directories and files like these:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;├── _config.yml
├── _posts
├── Gemfile
├── Gemfile.lock
├── index.md
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s what each of these directories and files is for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;_config.yml:&lt;/strong&gt; The Jekyll configuration file containing your site’s settings and options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;_posts:&lt;/strong&gt; A directory that contains your site’s content (can be blog posts). These can be Markdown or HTML files with a specific file naming convention: &lt;em&gt;YEAR-MONTH-DAY-title.MARKUP&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gemfile and Gemfile.lock:&lt;/strong&gt; Bundler uses these files to manage the Ruby gems on which your site relies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://index.md" rel="noopener noreferrer"&gt;&lt;strong&gt;index.md&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;:&lt;/strong&gt; The default homepage for your site, generated from a Markdown or HTML file.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But there are more files/folders that can be used to customize your Jekyll website. These folders include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;_includes:&lt;/strong&gt; A directory that contains reusable HTML snippets that can be included in your layouts and pages. Such as navbar, footer, e.t.c.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;_layouts:&lt;/strong&gt; A directory that contains HTML layout templates that define the structure of your pages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;assets:&lt;/strong&gt; A directory that contains any files that are used by your site, such as images and CSS files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;_sass:&lt;/strong&gt; A directory that contains Sass files that can be used to generate CSS for your site.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This file structure provides a solid foundation for a Jekyll project, but you can modify it as needed to suit the specific needs of your project.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Quick Start Option: Use Our GitHub Template&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As an alternative to starting your project using the Jekyll CLI, you can create a Git repository using Kinsta’s &lt;a href="https://github.com/kinsta/hello-world-jekyll" rel="noopener noreferrer"&gt;“Hello World” Jekyll template&lt;/a&gt; on GitHub. Select &lt;strong&gt;Use this template&lt;/strong&gt; &amp;gt; &lt;strong&gt;Create a new repository&lt;/strong&gt; to copy the starter code into a new repository within your own GitHub account.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Preview a Jekyll Site&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You now have a Jekyll site, but how can you preview the website to see what it looks like before you maybe start customizing it to suit your needs? Open your terminal and move into your project’s directory, then 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;jekyll serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate a &lt;strong&gt;_site&lt;/strong&gt; folder that includes all static files generated from your project. It will also start the Jekyll server, and you can preview your site via &lt;a href="http://localhost:4000" rel="noopener noreferrer"&gt;&lt;strong&gt;http://localhost:4000&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you visit the URL in your web browser, you should see your Jekyll site with the minima theme:&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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fminima-jekyll-theme.jpg%2520align%3D" 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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fminima-jekyll-theme.jpg%2520align%3D" alt="Jekyll static site default appearance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Default appearance&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Customize a Jekyll Site&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When you create a site with Jekyll and use a theme, you can customize the site to suit your needs. For example, you may want to add new pages, change a page’s layout, or adjust how some items are displayed. All these are possible with Jekyll.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How Front Matter Works in Jekyll&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When you open each page or blog post of your project folder, you will notice a block of information within three dashes (—) at the top of the page. This is referred to as &lt;strong&gt;front matter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is a metadata format used in Jekyll, to store information about a page or post — it can be written in either YAML or JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;Welcome&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Jekyll!&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Introduction&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;what&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Jekyll&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;about&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;how&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;it&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;works"&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;2023-03-07 16:54:37 +0100&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the front matter includes variables, such as the post’s title, description, and date. These variables can be used in the page or post’s layout or content.&lt;/p&gt;

&lt;p&gt;Jekyll parse’s the front matter and uses it to generate the output HTML for your site. You can use front matter to specify various options, such as layout, permalink, published status, etc.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;How To Configure Default Front Matter&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;You can also configure default front matter, so you don’t need to define the same front matter for similar files. For example, if each blog post uses the same author’s name and layout. You can define a custom front matter in your &lt;strong&gt;_config.yml&lt;/strong&gt; file to serve all your blog posts.&lt;/p&gt;

&lt;p&gt;The way it’s structured it’s a little bit complex, but here is what it will look like. Paste this below the last configuration in your &lt;strong&gt;_config.yml&lt;/strong&gt; file:&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;defaults&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt;
   &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;posts"&lt;/span&gt; &lt;span class="c1"&gt;# empty string means all files&lt;/span&gt;
   &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;post"&lt;/span&gt;
     &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;John&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Doe"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you now run the &lt;code&gt;jekyll serve&lt;/code&gt; command, you will notice that even when you don’t define the layout and author on each post, you still have access to them within your files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; When you don’t define a path, all files will use the defined front matter values.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Creating Pages in Jekyll&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When you create a file in the root directory of your project, it is considered a page. The name you give to the file is most times used in the URL, so you’ll name each page file a name that resonates well.&lt;/p&gt;

&lt;p&gt;For example, if you want to create a page with the URL &lt;a href="https://example.com/about" rel="noopener noreferrer"&gt;&lt;strong&gt;https://example.com/about&lt;/strong&gt;&lt;/a&gt;, create a file named &lt;strong&gt;about.html&lt;/strong&gt; or &lt;a href="http://about.md" rel="noopener noreferrer"&gt;&lt;strong&gt;about.md&lt;/strong&gt;&lt;/a&gt;. The file extension determines the markup language to use for the page content (HTML or Markdown).&lt;/p&gt;

&lt;p&gt;Once you have created a file, add appropriate front matter and content. Save the file and refresh your Jekyll site in the browser. The new page should now be accessible at the URL corresponding to the filename.&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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fcreate-new-page.jpg%2520align%3D" 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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fcreate-new-page.jpg%2520align%3D" alt="A Jekyll page consisting of front matter and content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Front matter and content&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Creating Layouts in Jekyll&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can use Layouts to define the structure and design of your site’s pages and posts. This is usually done majorly with HTML code. You can include a header, footer, meta information with the page’s metadata.&lt;/p&gt;

&lt;p&gt;The first step would be to create a &lt;strong&gt;_layouts&lt;/strong&gt; folder in your project’s root directory. Then create a file for each layout — the file should have a descriptive name that reflects the purpose of the layout. For example, you might create a file named &lt;strong&gt;page.htm&lt;/strong&gt;l to define the page layout for all pages on your site.&lt;/p&gt;

&lt;p&gt;It’s best to define the overall structure of your layouts with HTML or another markup language.&lt;/p&gt;

&lt;p&gt;You can include placeholders for any dynamic content that will be inserted into the layout, such as the page title, content, and metadata. For example, you might create a basic layout that includes a header, footer, and content area like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{ page.title }}&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
                &lt;span class="c"&gt;&amp;lt;!-- Navigation menu goes here --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;{{ content }}&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
            &lt;span class="c"&gt;&amp;lt;!-- Footer content goes here --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;{{ page.title }}&lt;/code&gt; and &lt;code&gt;{{ content }}&lt;/code&gt; placeholders will be replaced with the actual title and content of the page being rendered.&lt;/p&gt;

&lt;p&gt;At this point, any page or post that uses page as its layout value in its front matter will have this layout. You can create multiple layouts within the &lt;strong&gt;_layouts&lt;/strong&gt; folder and style your layouts however you like. You can also override a theme’s layout by defining a layout with a similar name.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How the _includes Folder Works in Jekyll&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;_includes&lt;/strong&gt; folder contains reusable snippets of code that you can include in different parts of your website. For example, you can create a &lt;strong&gt;navbar.html&lt;/strong&gt; file in your includes folder and add it to your &lt;strong&gt;page.html&lt;/strong&gt; layout file using the &lt;code&gt;{% include %}&lt;/code&gt; tag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{ page.title }} &lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;{% include navbar.html %} &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;{{ content }} &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
             &lt;span class="c"&gt;&amp;lt;!-- Footer content goes here --&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At build time, Jekyll will replace the tag with the content of &lt;strong&gt;navbar.html&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The  &lt;strong&gt;_includes&lt;/strong&gt; folder can contain any type of file, such as HTML, Markdown, or Liquid files. The principal aim is to keep your code DRY (Don’t Repeat Yourself) by allowing you to reuse code across your site.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Looping Through Posts in Jekyll&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You might want to create a dedicated blog page to hold all your blog posts, this means you’d want to fetch all the posts on your site and loop through them. With Jekyll it’s easy to achieve using the &lt;code&gt;{% for %}&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;All posts on any Jekyll website are stored in the &lt;code&gt;site.posts&lt;/code&gt; variable. You can loop through and use the &lt;code&gt;{{ post.title }}&lt;/code&gt; Liquid variable to output the title of each post this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{% for post in site.posts %}
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;{{ post.title }}&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
{% endfor %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use additional Liquid variables to output other information about each post, such as the post’s date or author:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
{% for post in site.posts %}
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;{{ post.title }}&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Published on {{ post.date | date: "%B %-d, %Y" }} by {{ post.author }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
{% endfor %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that in the example above, the date Liquid filter formats each post’s date in a more human-readable format.&lt;/p&gt;

&lt;p&gt;Now, you have an idea of some basic formatting that can be done to your Jekyll site. But you may not need to use all these to build a Jekyll site from scratch because you can always search for a theme that meets your needs and add it to your Jekyll site.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Add a Theme To a Jekyll Site&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;There are various easy-to-add themes, but the good thing is that for each theme, there is always clear information about how to install them in the ReadMe file on GitHub. You can decide to clone the theme, or if it is a &lt;a href="https://rubygems.org/search?query=jekyll-theme" rel="noopener noreferrer"&gt;gem-based theme&lt;/a&gt;, the process is easier.&lt;/p&gt;

&lt;p&gt;For this article, you would install a &lt;a href="https://rubygems.org/gems/jekyll-theme-clean-blog" rel="noopener noreferrer"&gt;blog theme&lt;/a&gt; and customize it to have a &lt;a href="https://myblog-84b54.kinsta.app/" rel="noopener noreferrer"&gt;blog site deployed to Kinsta&lt;/a&gt;. This is a gen-based theme and you can access its &lt;a href="https://github.com/StartBootstrap/startbootstrap-clean-blog-jekyll" rel="noopener noreferrer"&gt;source code&lt;/a&gt; and &lt;a href="https://github.com/StartBootstrap/startbootstrap-clean-blog-jekyll#readme" rel="noopener noreferrer"&gt;instructions on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To add a gem-based theme, open your site’s Gemfile and add the gem for the theme you want to use. The theme we will use is the &lt;strong&gt;jekyll-theme-clean-blog&lt;/strong&gt;. You can replace the default &lt;strong&gt;minima&lt;/strong&gt; theme in the Gemfile:&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="s"&gt;gem "jekyll-theme-clean-blog"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the &lt;code&gt;bundle install&lt;/code&gt; command in your site’s directory to install the theme’s gem and its dependencies.&lt;/p&gt;

&lt;p&gt;In your site’s &lt;strong&gt;_config.yml&lt;/strong&gt; file, add the following line to specify the theme you want to use:&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;theme&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jekyll-theme-clean-blog&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, your theme is ready for use.&lt;/p&gt;

&lt;p&gt;You will want to remove all layouts in the &lt;strong&gt;_layouts&lt;/strong&gt; directory to avoid them overriding the theme’s layout.&lt;/p&gt;

&lt;p&gt;You can then find the layout names for your files in the &lt;a href="https://github.com/StartBootstrap/startbootstrap-clean-blog-jekyll#using-rubygems" rel="noopener noreferrer"&gt;theme’s documentation&lt;/a&gt;. For example, if you’re using the &lt;strong&gt;jekyll-theme-clean-blog&lt;/strong&gt; theme, the layout names for the &lt;strong&gt;index.html&lt;/strong&gt; file is &lt;strong&gt;home&lt;/strong&gt;, other pages is &lt;strong&gt;page&lt;/strong&gt;, and all posts is &lt;strong&gt;post&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Finally, run &lt;code&gt;jekyll serve&lt;/code&gt; to build and serve your site using the new theme.&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%2Fuploads%2Farticles%2Flo7wvg51bflkbwic9szr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flo7wvg51bflkbwic9szr.jpg" alt="Jekyll blog static site"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jekyll blog static site&lt;/p&gt;

&lt;p&gt;That’s it! Your Jekyll site should now be using the new gem-based theme you added. You can customize the theme further by modifying its layout in your site’s &lt;strong&gt;_layouts&lt;/strong&gt; directories.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Customize a Jekyll Theme&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You now have your theme added to your site, the next action would be to customize the site to meet your needs and work as it is intended to work. For example, the images for each page and post are not displayed rather it displays a grey background.&lt;/p&gt;

&lt;p&gt;You can fix this by adding a front matter option to each page and post by specifying the path to an image you wish to use. In Jekyll, assets such as images are stored in the &lt;strong&gt;assets&lt;/strong&gt; folder. In this folder, you can decide to create sub-folders to organize your images.&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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fjekyll-assets.jpg%2520align%3D" 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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fjekyll-assets.jpg%2520align%3D" alt="Organizing image folder for Jekyll site"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image folder&lt;/p&gt;

&lt;p&gt;You can now add a background option to the front matter block and a path to its image. For example, on the about page, this is the front matter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;page&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;About&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;This is the page description.&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;/about/&lt;/span&gt;
&lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/assets/images/about-page.jpeg'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do this for all pages and posts and your page will look like this:&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%2Fuploads%2Farticles%2Fk3h9abdvwfk6xprocw7f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3h9abdvwfk6xprocw7f.jpg" alt="Background image is shown on the About page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Background image is shown on the About page&lt;/p&gt;

&lt;p&gt;Another customization you can do is adjust the navbar options. For example, you may not need a contact page, meaning you should remove its link from the navbar options. You can do this by studying the &lt;a href="https://github.com/StartBootstrap/startbootstrap-clean-blog-jekyll/blob/master/_includes/navbar.html" rel="noopener noreferrer"&gt;theme’s source code&lt;/a&gt;, noticing the file responsible for the nav links, and replicating the file exactly in your project, removing the option you don’t need.&lt;/p&gt;

&lt;p&gt;The nav links are in the &lt;a href="https://github.com/StartBootstrap/startbootstrap-clean-blog-jekyll/blob/master/_includes/navbar.html" rel="noopener noreferrer"&gt;_includes folder’s navbar.html file&lt;/a&gt;. You can create this file, paste the code from your source code, and remove the contact option or add any new option you wish.&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%2Fuploads%2Farticles%2Fk5pijh5g017r8fzht3xa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5pijh5g017r8fzht3xa.jpg" alt="Customizing the navbar from the Jekyll theme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Customizing the navbar from the Jekyll theme&lt;/p&gt;

&lt;p&gt;When you save your project, you will notice the nav options will be customized:&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%2Fuploads%2Farticles%2Ff1kog8tl9v23k655cvum.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff1kog8tl9v23k655cvum.jpg" alt="Fully customized nav bar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fully customized nav bar&lt;/p&gt;

&lt;p&gt;Finally, one last customization would be creating a posts page that will hold all your blog posts — which means you will loop through all the posts on this page.&lt;/p&gt;

&lt;p&gt;Create a file, &lt;strong&gt;posts.html&lt;/strong&gt; and paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;---
layout: page
title: Blog
description: Expand your knowledge and stay informed with our engaging blog posts.
background: '/assets/images/blog-page.jpeg'
---

{% for post in site.posts %}

&lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-preview"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ post.url | prepend: site.baseurl | replace: '//', '/' }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ post.title }}&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
        {% if post.subtitle %}
        &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-subtitle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ post.subtitle }}&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
        {% else %}
        &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-subtitle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            {{ post.excerpt | strip_html | truncatewords: 15 }}
        &lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
        {% endif %}
    &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-meta"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Posted by {% if post.author %} {{ post.author }} {% else %} {{ site.author
        }} {% endif %} on {{ post.date | date: '%B %d, %Y' }} · {% include
        read_time.html content=post.content %}
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;hr&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

{% endfor %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feel free to adjust the background image to reflect your saved image. In the code above, you are looping through all the posts to display all posts on this page. This is what the posts page will look like when saved.&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%2Fuploads%2Farticles%2Fb5sloetzgntnlo3roobe.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5sloetzgntnlo3roobe.jpg" alt="Adding a special posts page to display all posts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Posts page&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Add Content To a Jekyll Site&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You have now created a Jekyll site and configured the site to meet your needs. The last step would be to add content or learn how content can be added to a Jekyll site.&lt;/p&gt;

&lt;p&gt;All content is stored in the &lt;em&gt;posts folder. Each content is stored in a file with a similar naming convention of&lt;/em&gt; &lt;a href="http://YYYY-MM-DD-title.md" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;YYYY-MM-DD-title.md&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;em&gt;(or&lt;/em&gt; &lt;strong&gt;&lt;em&gt;.html&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;for HTML files). For example, if you want to create a post called “My First Post”, create a&lt;/em&gt; &lt;a href="http://2023-03-08-my-first-post.md" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;2023-03-08-my-first-post.md&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;em&gt;in the&lt;/em&gt; &lt;strong&gt;posts&lt;/strong&gt; directory.&lt;/p&gt;

&lt;p&gt;Next, for each post/content file, ensure you add front matter about the post at the top. This will include the layout, title, description, date and other information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Read&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Books:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Tips&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Strategies&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Maximum&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Learning"&lt;/span&gt;
&lt;span class="na"&gt;subtitle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Reading&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;books&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;one&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;of&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;most&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;powerful&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ways&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;learn&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;new&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;information,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;gain&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;new&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;perspectives,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;expand&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;your&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;knowledge."&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2023-03-02 23:45:13 -0400&lt;/span&gt;
&lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/assets/images/blog/books.jpeg'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can add your content below the front matter block with HTML tags or markdown syntax.&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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fpost-with-frontmatter-and-content.jpg%2520align%3D" 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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fpost-with-frontmatter-and-content.jpg%2520align%3D" alt="Adding new posts to the _posts folder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding new posts to the _posts folder&lt;/p&gt;

&lt;p&gt;Save the file, and Jekyll will automatically build and include it in your site.&lt;/p&gt;

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

&lt;p&gt;So far, you have learned how Jekyll works and the various customizations that you can do with Jekyll. It’s now safe to agree that Jekyll is an excellent tool for creating static websites due to its simplicity, flexibility, and powerful features.&lt;/p&gt;

&lt;p&gt;Jekyll’s intuitive templating system, liquid templates, and built-in support for markdown and other markup languages make it easy to create and manage content-rich sites quickly.&lt;/p&gt;

&lt;p&gt;Feel free to host all your static websites with &lt;a href="https://kinsta.com/application-hosting/" rel="noopener noreferrer"&gt;Kinsta’s Application Hosting for free&lt;/a&gt;, and if you like it, opt for our &lt;a href="https://kinsta.com/application-hosting/pricing/hobby-tier/" rel="noopener noreferrer"&gt;Hobby Tier&lt;/a&gt; plan, &lt;strong&gt;starting at $7/month&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What is your thought on Jekyll? Have you utilized Jekyll to build anything? Please feel free to share your projects and experiences with us in the comments section below.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>jekyll</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>The 3 Best Svelte Static Site Generators You Need to Try</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Wed, 18 Oct 2023 13:00:00 +0000</pubDate>
      <link>https://dev.to/kinsta/top-3-svelte-static-site-generators-for-maximum-performance-8ca</link>
      <guid>https://dev.to/kinsta/top-3-svelte-static-site-generators-for-maximum-performance-8ca</guid>
      <description>&lt;p&gt;In recent years, &lt;a href="https://kinsta.com/blog/static-site-generator/" rel="noopener noreferrer"&gt;static site generators&lt;/a&gt; (SSGs) have experienced a surge in popularity among developers because of their simplicity, speed, and security benefits. They’re often used for blogs, documentation, portfolios, and &lt;a href="https://kinsta.com/blog/open-source-ecommerce/" rel="noopener noreferrer"&gt;ecommerce sites&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Take a closer look at several static site generators that use Svelte and discuss why they could be a game-changer for your next &lt;a href="https://kinsta.com/wordpress-hosting/" rel="noopener noreferrer"&gt;web development projects&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Top 3 Svelte Static Site Generators&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before we review some of these static site generators, you should understand that SSGs will always generate static files, which you’d need to host online for your users to have access to the website.&lt;/p&gt;

&lt;p&gt;With Kinsta, you can host your &lt;a href="https://kinsta.com/knowledgebase/what-is-a-static-website/" rel="noopener noreferrer"&gt;static website&lt;/a&gt; through our &lt;a href="https://kinsta.com/application-hosting/" rel="noopener noreferrer"&gt;Application Hosting solution&lt;/a&gt; which offers you scalability, reliability, and security. We’re currently working on adding new, dedicated &lt;a href="https://kinsta.com/docs/static-site-hosting/" rel="noopener noreferrer"&gt;static site hosting&lt;/a&gt; services that will allow you to deploy your SSGs more efficiently and serve your content even faster.&lt;/p&gt;

&lt;p&gt;Let’s now explore some best static site generators that use Svelte and what makes them stand out.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. SvelteKit&lt;/strong&gt;
&lt;/h3&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%2Fuploads%2Farticles%2Fymz5kaj2h0ojdtbabqk5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymz5kaj2h0ojdtbabqk5.jpg" alt="The SvelteKit homepage."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SvelteKit&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kit.svelte.dev/" rel="noopener noreferrer"&gt;SvelteKit&lt;/a&gt; is a popular SSG built on top of the Svelte framework that takes advantage of Svelte’s unique features, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Compiler-based approach&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reactive updates&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Component-based architecture&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Smaller bundle sizes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easy to learn&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was built by the Svelte team and is widely considered one of the best SSGs that use Svelte for the following reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SvelteKit has built-in serverless functions, making it easy to add backend functionality to your website. For example, you could use a serverless function to handle form submissions, process payments, or interact with a &lt;a href="https://kinsta.com/database-hosting/pricing/" rel="noopener noreferrer"&gt;database&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SvelteKit automatically code-splits your application, which means that it only loads the code that’s needed for each page. This results in faster load times and better performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SvelteKit can pre-fetch data for a page before it’s loaded, which means that the page can be rendered faster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SvelteKit comes with built-in routing, which makes it easy to create complex multi-page applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SvelteKit is used by many popular websites, including Yarn and Brilliant. If you’re looking for a Svelte SSG, SvelteKit is definitely worth a try. Make sure to check out their &lt;a href="https://kit.svelte.dev/docs/introduction" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; which provides comprehensive documentation on how to get started and more.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;How To Deploy a SvelteKit Static Site on Kinsta&lt;/strong&gt;
&lt;/h4&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%2Fuploads%2Farticles%2Flj76uu1ndvw8uquvzdik.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flj76uu1ndvw8uquvzdik.jpg" alt="SvelteKit quick start"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SvelteKit quick start&lt;/p&gt;

&lt;p&gt;You can set up a SvelteKit static site on Kinsta by forking our &lt;a href="https://github.com/olawanlejoel/sveltekit-quickstart" rel="noopener noreferrer"&gt;quick start example&lt;/a&gt; and deploying it to our &lt;a href="https://kinsta.com/application-hosting/" rel="noopener noreferrer"&gt;Application hosting&lt;/a&gt;. This will provide you with a URL that loads up your SvelteKit static site within minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Astro&lt;/strong&gt;
&lt;/h3&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%2Fuploads%2Farticles%2Fpybia4t8mufsolvt2lcx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpybia4t8mufsolvt2lcx.jpg" alt="The Astro homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Astro&lt;/p&gt;

&lt;p&gt;Astro is a modern static site generator that provides a flexible and efficient way to build static websites. It is designed to be fast, lightweight, and easy to use, making it a great choice for developers who want to build performant and easy-to-maintain websites.&lt;/p&gt;

&lt;p&gt;Astro is designed around a component-driven development model, which makes it easy to create reusable components and manage their state and data flow. You also have the ability to use your favorite frontend frameworks like Svelte, &lt;a href="https://kinsta.com/knowledgebase/what-is-react-js/" rel="noopener noreferrer"&gt;React&lt;/a&gt;, and &lt;a href="https://kinsta.com/blog/vue-js/" rel="noopener noreferrer"&gt;Vue&lt;/a&gt; to create components that you can easily integrate into Astro pages and templates.&lt;/p&gt;

&lt;p&gt;It also utilizes the &lt;a href="https://docs.astro.build/en/concepts/islands/" rel="noopener noreferrer"&gt;Island architecture&lt;/a&gt;, a unique approach that separate pages and components into isolated “islands” of code (CSS, JavaScript, and HTML).&lt;/p&gt;

&lt;p&gt;Astro also gives you access to &lt;a href="https://astro.build/integrations/" rel="noopener noreferrer"&gt;so many integrations&lt;/a&gt;, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MDX Integration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Image optimization Integration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kinsta.com/blog/tailwind-css/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt; Integration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sitemap Integration&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Astro is used by many popular websites like &lt;a href="https://theguardian.engineering/open-source" rel="noopener noreferrer"&gt;The Guardian Engineering&lt;/a&gt;. You can check out other popular platforms that use them on their &lt;a href="https://astro.build/showcase/" rel="noopener noreferrer"&gt;showcase page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.astro.build/" rel="noopener noreferrer"&gt;documentation for Astro&lt;/a&gt; provides detailed information on how to use the framework, including its &lt;a href="https://docs.astro.build/en/guides/integrations-guide/svelte/" rel="noopener noreferrer"&gt;integration with the Svelte framework&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;How To Deploy an Astro Static Site on Kinsta&lt;/strong&gt;
&lt;/h4&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%2Fuploads%2Farticles%2Fnp9p5f0ot2h0v3a7kwjg.jpeg" 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%2Fuploads%2Farticles%2Fnp9p5f0ot2h0v3a7kwjg.jpeg" alt="Astro quick start example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Astro quick start&lt;/p&gt;

&lt;p&gt;You can easily set up an Astro website by forking &lt;a href="https://github.com/kinsta/hello-world-astro" rel="noopener noreferrer"&gt;Kinsta’s hello-world quickstart example&lt;/a&gt; on GitHub. Then deploy it to Kinsta’s &lt;a href="https://kinsta.com/application-hosting/" rel="noopener noreferrer"&gt;Application hosting&lt;/a&gt;, which would provide you with a unique URL.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Elder.js&lt;/strong&gt;
&lt;/h3&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%2Fuploads%2Farticles%2Feybpquglwk6kpo4ydtyy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feybpquglwk6kpo4ydtyy.jpg" alt="The Elder.js homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Elder.js&lt;/p&gt;

&lt;p&gt;Elder.js is a static site generator built with &lt;a href="https://kinsta.com/seo/" rel="noopener noreferrer"&gt;SEO&lt;/a&gt; in mind. A small team of SEOs and developers designed it from the ground up to solve the unique challenges and complexities of building flagship SEO sites with 100k+ pages.&lt;/p&gt;

&lt;p&gt;One of the key features of Elder.js is its ability to work seamlessly with Svelte, giving developers the possibility to create reusable UI components and use them across multiple pages or even projects.&lt;/p&gt;

&lt;p&gt;On top of being able to integrate with Svelte, Elder.js has other interesting features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Elder.js uses a highly optimized build process that utilizes as many CPU cores as possible, making it incredibly fast and efficient. For instance, according to their &lt;a href="https://github.com/Elderjs/elderjs#elderjs-an-seo-first-svelte-framework--static-site-generator" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, it can easily generate a data-intensive 18,000-page site in just 8 minutes using only a 4-core VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With Elder.js, developers have complete control over how they fetch, prepare, and manipulate data before sending it to their Svelte template.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Elder.js supports a range of &lt;a href="https://github.com/Elderjs/plugins#official-plugins" rel="noopener noreferrer"&gt;official&lt;/a&gt; and &lt;a href="https://github.com/Elderjs/plugins#other-plugins" rel="noopener noreferrer"&gt;community plugins&lt;/a&gt; that can be added to a site to extend its functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Elder.js supports shortcodes, which are smart placeholders that can be used to future-proof content whether it lives in a &lt;a href="https://kinsta.com/blog/cms-software/" rel="noopener noreferrer"&gt;CMS&lt;/a&gt; or &lt;a href="https://kinsta.com/blog/wordpress-vs-static-html/" rel="noopener noreferrer"&gt;static files&lt;/a&gt;. These shortcodes can be asynchronous, making it easy to include dynamic content on a site.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Elder.js allows developers to hydrate just the parts of the client that need to be interactive, reducing payload size and improving site performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check the &lt;a href="https://elderguide.com/tech/elderjs/" rel="noopener noreferrer"&gt;official Elder.js documentation&lt;/a&gt; for more information.&lt;/p&gt;

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

&lt;p&gt;Static site generators (SSGs) are becoming increasingly popular due to their speed, simplicity, and enhanced security. They are particularly useful for building websites that don’t require dynamic content or functionality from a server.&lt;/p&gt;

&lt;p&gt;Using Svelte-based SSGs could give you even more advantages because it provides additional features from the Svelte framework, including a smaller bundle size and rapid rendering. As a result, Svelte-based SSGs are an excellent choice for creating static sites that load quickly and operate efficiently.&lt;/p&gt;

&lt;p&gt;You can host your static website with &lt;a href="https://kinsta.com/application-hosting/" rel="noopener noreferrer"&gt;Kinsta’s Application Hosting for free&lt;/a&gt;, and if you like it, upgrade to our &lt;a href="https://kinsta.com/application-hosting/pricing/hobby-tier/" rel="noopener noreferrer"&gt;Hobby Tier&lt;/a&gt; plan.&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What Is Astro? An Introduction to the Popular Static Site Generator</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Wed, 11 Oct 2023 13:00:00 +0000</pubDate>
      <link>https://dev.to/kinsta/what-is-astro-an-introduction-to-the-popular-static-site-generator-1ilh</link>
      <guid>https://dev.to/kinsta/what-is-astro-an-introduction-to-the-popular-static-site-generator-1ilh</guid>
      <description>&lt;p&gt;Web development has evolved significantly from static single-page websites to offering a variety of languages, frameworks, and systems for every niche.&lt;/p&gt;

&lt;p&gt;Now we have Astro, a new and easy-to-use tool by Fred K. Schott and a group of other contributors. Developers love it because it’s simple like old-school web pages but powerful.&lt;/p&gt;

&lt;p&gt;We'll explain why it's popular and how you can use Astro to easily make a blog!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Is Astro?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://kinsta.com/blog/svelte-static-site-generator/#2-astro" rel="noopener noreferrer"&gt;Astro&lt;/a&gt;, or Astro.js, is a popular &lt;a href="https://kinsta.com/blog/static-site-generator/" rel="noopener noreferrer"&gt;static site generator&lt;/a&gt; conceived for those who want to create content-rich websites that run quickly and smoothly. Its lightweight nature, intuitive structure, and gentle learning curve make it attractive to developers of all experience levels.&lt;/p&gt;

&lt;p&gt;Despite its small footprint, Astro comes with powerful tools that drastically increase your site’s flexibility, saving you hours in content and theme management. In addition, it gives developers the option of working with their preferred frameworks in conjunction with Astro — an appealing prospect for seasoned coders who already have a host of favorites.&lt;/p&gt;

&lt;p&gt;Here are just a few of the ways Astro stands out from the crowd:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Island architecture:&lt;/strong&gt; Astro extracts your user interface (UI) into smaller, isolated components known as “Astro Islands” that can be used on any page. Unused JavaScript is replaced with lightweight HTML.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero JavaScript (by default):&lt;/strong&gt; While you can use all the JavaScript you want to create your websites, Astro will attempt to deploy zero JavaScript to production by transcribing your code for you. This a perfect approach if your focus is on site speed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SSG and SSR included:&lt;/strong&gt; Astro started as a static site generator, but along the way, it became a framework that uses both static site generation (SSG) and &lt;a href="https://kinsta.com/blog/web-application-architecture/#serversiderendered-architecture" rel="noopener noreferrer"&gt;server-side rendering (SSR)&lt;/a&gt;. And you can pick which pages will use which approach.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Framework-agnostic:&lt;/strong&gt; When using Astro, you can use any &lt;a href="https://kinsta.com/blog/javascript-libraries/" rel="noopener noreferrer"&gt;JavaScript framework&lt;/a&gt; you like — even multiple frameworks at once. (We’ll discuss this in greater detail later in this article.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What’s more, Astro is edge-ready, meaning it can be deployed anywhere, anytime, with ease.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Astro’s Structure&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before we venture any further, it’s important to understand how Astro is set up so you can use it effectively. Let’s take a look at Astro’s core file structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── dist/
├── src/
│   ├── components/
│   ├── layouts/
│   └── pages/
│       └── index.astro
├── public/
└── package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the structure itself is quite simple. However, there are some key points you should remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Most of our project lives in the &lt;strong&gt;src&lt;/strong&gt; folder. You can arrange your components, layouts, and pages into subfolders. You may add additional folders to make your project easier to navigate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;public&lt;/strong&gt; folder is for all the files that live outside of the build process, such as fonts, images, or a &lt;strong&gt;robots.txt&lt;/strong&gt; file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;dist&lt;/strong&gt; folder will contain all the content you want to deploy on your production server.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, let’s dive deeper into Astro’s main constituents: components, layouts, and pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Components&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Components are reusable chunks of code that can be included all over your website, similar to &lt;a href="https://kinsta.com/blog/wordpress-shortcodes/" rel="noopener noreferrer"&gt;shortcodes in WordPress&lt;/a&gt;. By default, they have the file extension &lt;strong&gt;.astro&lt;/strong&gt;, but you can also use non-Astro components built with &lt;a href="https://kinsta.com/blog/vue-js/" rel="noopener noreferrer"&gt;Vue&lt;/a&gt;, &lt;a href="https://kinsta.com/blog/react-static-site-generator/#4-astro" rel="noopener noreferrer"&gt;React&lt;/a&gt;, Preact, or &lt;a href="https://kinsta.com/blog/svelte-static-site-generator/#2-astro" rel="noopener noreferrer"&gt;Svelte&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The following is an example of what a simple component looks like — in this case, a classed &lt;code&gt;div&lt;/code&gt; tag containing an &lt;code&gt;h2&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- src/components/Kinsta.astro --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"kinsta_component"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Hello, Kinsta!&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here’s how we can incorporate that component into our site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;KinstaComponent&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Kinsta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;astro&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;KinstaComponent&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As demonstrated above, you first have to import the component. Only then can it be included on the page.&lt;/p&gt;

&lt;p&gt;Now it’s time to add some properties to our component. Let’s start with a &lt;code&gt;{title}&lt;/code&gt; property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Astro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"kinsta_component"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here’s how our property would be implemented:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;KinstaComponent&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Kinsta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;astro&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;!--&lt;/span&gt; &lt;span class="na"&gt;This&lt;/span&gt; &lt;span class="na"&gt;shows&lt;/span&gt; &lt;span class="s"&gt;"Good day"&lt;/span&gt; &lt;span class="err"&gt;--&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;KinstaComponent&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Good day"&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;!--&lt;/span&gt; &lt;span class="na"&gt;This&lt;/span&gt; &lt;span class="na"&gt;shows&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt; &lt;span class="err"&gt;--&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;KinstaComponent&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
 &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple, right?&lt;/p&gt;

&lt;p&gt;As you’ve probably already realized, the real power of Astro’s components is in their global and reusable nature. They enable you to make sweeping changes to your entire site by editing only a few lines of code, which can save you countless hours that would otherwise be spent on tedious, painstaking text replacements.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Layouts&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now, let’s talk about layouts. In addition to their familiar thematic function, layouts in Astro are also reusable components, but they’re employed as code wrappers.&lt;/p&gt;

&lt;p&gt;Take a look at this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="c1"&gt;// src/layouts/Base.astro&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pageTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Astro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;charset&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pageTitle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;slot&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the &lt;code&gt;&amp;lt;slot /&amp;gt;&lt;/code&gt; tag here. The &lt;code&gt;&amp;lt;slot /&amp;gt;&lt;/code&gt; element in Astro acts as a placeholder for actual HTML tags and content.&lt;/p&gt;

&lt;p&gt;Let’s see it in action.&lt;/p&gt;

&lt;p&gt;The code below shows our &lt;code&gt;&amp;lt;slot /&amp;gt;&lt;/code&gt; tag getting replaced with our desired code, all of which is wrapped by our &lt;strong&gt;Base.astro&lt;/strong&gt; layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Base&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../layouts/Base.astro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Hello world"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Some example text.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, our &lt;code&gt;&amp;lt;slot /&amp;gt;&lt;/code&gt; tag was replaced by the HTML it represents, which is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Some example text.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, layouts, like components, allow you to reuse chunks of code across your site, simplifying the challenge of updating your global content and design.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Pages&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Pages are a special type of component that is responsible for routing, data loading, and templating.&lt;/p&gt;

&lt;p&gt;Astro uses file-based routing to generate pages, rather than dynamic routing. Not only does the file-based method consume less bandwidth, but it also saves you from having to import your components manually.&lt;/p&gt;

&lt;p&gt;Here’s an example of defined routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;src/pages/index.astro =&amp;gt; yourdomain.com
src/pages/test.astro =&amp;gt; domain.com/test
src/pages/test/subpage =&amp;gt; domain.com/test/subpage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these routes, our resulting homepage would be rendered as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- src/pages/index.astro --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello, Kinsta&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But we already know how to use layouts, so let’s convert this into something that’s globally accessible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Base&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../layouts/Base.astro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello, Kinsta&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There – that’s much cleaner.&lt;/p&gt;

&lt;p&gt;We’ll discuss routing in Astro in more detail later in this article, but for now, let’s move on to the fun stuff: site construction and customization.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Customizing and Extending Astro&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;It’s time to learn how to customize your Astro site! We’re going to use Markdown collections, routing, image handling, and an integration with React to build out and personalize our static site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ace.kinsta.io/editor/load/69" rel="noopener noreferrer"&gt;🎈&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Unlock a new level of performance and ease with Kinsta&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Find out why bloggers, agencies, and Fortune 500 companies are choosing Kinsta to host, build, and launch their websites, applications, and databases.&lt;/span&gt;&lt;/p&gt;
&lt;a href="https://kinsta.com/schedule-demo/" rel="noopener noreferrer"&gt;&lt;span&gt;Book a Demo&lt;/span&gt;&lt;/a&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Markdown Collections&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With version 2.0, Astro &lt;a href="https://astro.build/blog/astro-2/#automatic-type-safety-for-markdown--mdx" rel="noopener noreferrer"&gt;introduced&lt;/a&gt; a much better way to maintain Markdown content than before. Thanks to collections, we can be sure that all our frontmatter data is included and has the correct type of association.&lt;/p&gt;

&lt;p&gt;Lately, in version 2.5, they &lt;a href="https://astro.build/blog/astro-250/" rel="noopener noreferrer"&gt;added a possibility to also manage JSON and YAML files&lt;/a&gt; as collections.&lt;/p&gt;

&lt;p&gt;Ready to get your hands dirty?&lt;/p&gt;

&lt;p&gt;First, put all your Markdown articles in the &lt;strong&gt;src/content/collection_name&lt;/strong&gt; folder. We’re going to create a blog collection for this project, so in our demonstration, the folder will be &lt;strong&gt;src/content/blog&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now it’s time to define all the required frontmatter fields in our &lt;strong&gt;src/content/config.ts&lt;/strong&gt; file. Our blog will need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;title&lt;/code&gt; (string)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;tags&lt;/code&gt; (array)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;publishDate&lt;/code&gt; (time)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;image&lt;/code&gt; (string, optional)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what it all looks like put together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defineCollection&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blogCollection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineCollection&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
    &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;publishDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blogCollection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is what our &lt;a href="http://article-about-astro.md" rel="noopener noreferrer"&gt;&lt;strong&gt;article-about-astro.md&lt;/strong&gt;&lt;/a&gt; Markdown file contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Article about Astro&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;tag1&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;tag3&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;publishDate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2023-03-01&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="gu"&gt;## Tamen risit&lt;/span&gt;

Lorem &lt;span class="ge"&gt;*markdownum flumina*&lt;/span&gt;, laceraret quodcumque Pachyne, &lt;span class="gs"&gt;**alter**&lt;/span&gt; enim
cadavera choro.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;True, there’s nothing special about our Markdown file. But there’s some hidden magic here that will manifest if we make a typo.&lt;/p&gt;

&lt;p&gt;Let’s say, for instance, that instead of typing &lt;code&gt;publishDate&lt;/code&gt;, we accidentally typed &lt;code&gt;publishData&lt;/code&gt;. In the case of a misspelling like this, Astro will throw an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;blog → article-about-astro.md frontmatter does not match collection schema.
  &lt;span class="s2"&gt;"publishDate"&lt;/span&gt; is required.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Amazing, right? This nifty feature can help us find errors relating to frontmatter in a matter of seconds.&lt;/p&gt;

&lt;p&gt;The last thing we need to add is a page showing our data. Let’s create a file at &lt;strong&gt;src/page/blog/[slug].astro&lt;/strong&gt; with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Base&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../layouts/Base.astro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getCollection&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blogEntries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;blogEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Astro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks to &lt;code&gt;getStaticPaths&lt;/code&gt;, Astro will create all the static pages for each post in the blog collection.&lt;/p&gt;

&lt;p&gt;The only thing we’re missing now is a listing of all our articles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Base&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../layouts/Base.astro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getCollection&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blogEntries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;blogEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/blog/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, using collections makes this task remarkably simple.&lt;/p&gt;

&lt;p&gt;Now, let’s create a data type collection. First, we must open the &lt;strong&gt;src/content/config.ts&lt;/strong&gt; file again and add a new data collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defineCollection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;referenece&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blogCollection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineCollection&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;publishDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authorsCollection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineCollection&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blogCollection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;authorsCollection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apart from creating a new collection, we also added the &lt;strong&gt;author&lt;/strong&gt; reference in the &lt;strong&gt;blogCollection&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Time to create a new author. We must create a file called &lt;strong&gt;maciek-palmowski.json&lt;/strong&gt; in the content/authors.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fullName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Maciek Palmowski&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;country&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Poland&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last thing left is to grab this data in our Post. To do so, we’ll need to use &lt;a href="https://docs.astro.build/en/reference/api-reference/#getentry" rel="noopener noreferrer"&gt;getEntry&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Base&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../layouts/Base.astro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getCollection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getEntry&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blogEntries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;blogEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Astro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getEntry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Author: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Routing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Astro has two different routing modes. We already learned about the first – static (file-based) routing – when we covered pages earlier.&lt;/p&gt;

&lt;p&gt;Now we’re going to shift our focus to dynamic routing.&lt;/p&gt;

&lt;p&gt;Using dynamic route parameters, you can instruct an Astro page file to automate the creation of multiple pages with the same structure. This is useful when you have a lot of one particular type of page (think author bios, user profiles, documentation articles, and so on).&lt;/p&gt;

&lt;p&gt;For this next example, we’ll work on generating bio pages for our authors.&lt;/p&gt;

&lt;p&gt;In Astro’s default static output mode, these pages are generated at build time, meaning you must predetermine the list of authors that get a corresponding file. In dynamic mode, on the other hand, pages are generated upon request for any route that matches.&lt;/p&gt;

&lt;p&gt;If you want to pass a variable as your filename, add brackets around it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;pages/blog/[slug].astro -&amp;gt; blog/test, blog/about-me 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s dive deeper into this using the code from our &lt;strong&gt;src/page/blog/[slug]&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Base&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../layouts/Base.astro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getCollection&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blogEntries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;blogEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Astro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;getStaticPaths&lt;/code&gt; route is responsible for generating all the static pages. It returns two objects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;params&lt;/code&gt;&lt;strong&gt;:&lt;/strong&gt; Used to fill the brackets in our URLs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;props&lt;/code&gt;&lt;strong&gt;:&lt;/strong&gt; All the values we’re passing to the page&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And with that, your page generation is taken care of.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Image Handling&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We can’t talk about performant websites without bringing up &lt;a href="https://kinsta.com/blog/image-file-types/" rel="noopener noreferrer"&gt;modern image formats&lt;/a&gt;, correct resizing methods, and lazy loading.&lt;/p&gt;

&lt;p&gt;Luckily, Astro’s got us covered here, too. Thanks to the &lt;code&gt;@astrojs/image&lt;/code&gt; package, we can introduce all the above in a matter of minutes.&lt;/p&gt;

&lt;p&gt;After &lt;a href="https://docs.astro.build/en/guides/integrations-guide/image/" rel="noopener noreferrer"&gt;installing the package&lt;/a&gt;, we gain access to two components: &lt;code&gt;Image&lt;/code&gt; and &lt;code&gt;Picture&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Image&lt;/code&gt; component is used to create an optimized &lt;code&gt;&amp;lt;img /&amp;gt;&lt;/code&gt; tag. Here’s an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@astrojs/image/components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;heroImage&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../assets/hero.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;heroImage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"avif"&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"descriptive text"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;heroImage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"descriptive text"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;heroImage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"descriptive text"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, the &lt;code&gt;Picture&lt;/code&gt; component creates an optimized &lt;code&gt;&amp;lt;picture/&amp;gt;&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Picture&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@astrojs/image/components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;hero&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../assets/hero.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Picture&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;hero&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;widths&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"(max-width: 800px) 100vw, 800px"&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"descriptive text"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;SSG vs SSR&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;By default, Astro runs as a static site generator. This means that all the content is converted to static HTML pages.&lt;/p&gt;

&lt;p&gt;While this is a perfect approach from many perspectives (especially speed-related), we might sometimes prefer a more dynamic approach. If you want a separate profile page for each user, for example, or if you have thousands of articles on your site, re-rendering everything each time would be far too time-consuming.&lt;/p&gt;

&lt;p&gt;Luckily, Astro also can work as a fully server-side-rendered framework instead or in a hybrid mode between the two.&lt;/p&gt;

&lt;p&gt;To enable side-wide SSR, we need to add the following code to &lt;strong&gt;astro.config.mjs&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro/config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the standard approach.&lt;/p&gt;

&lt;p&gt;The hybrid approach means that by default, everything is dynamically generated, apart from the pages with &lt;code&gt;export const prerender = true&lt;/code&gt; added.&lt;/p&gt;

&lt;p&gt;With Astro 2.5, there is also the possibility to &lt;a href="https://astro.build/blog/astro-250/#static-by-default-hybrid-rendering-experimental" rel="noopener noreferrer"&gt;set static rendering as default and select dynamic routes manually&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to those, we can, for example, create a fully statically generated website with dynamic login and profile pages. Neat, right?&lt;/p&gt;

&lt;p&gt;You can read more about this in the &lt;a href="https://docs.astro.build/en/guides/server-side-rendering/" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Integrating Other JavaScript Frameworks&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Another amazing feature of Astro allows you to bring along your favorite framework and use it in concert with Astro. You can mix Astro with React, Preact, Svelte, Vue, Solid, or Alpine (for all integrations, see &lt;a href="https://docs.astro.build/en/guides/integrations-guide/" rel="noopener noreferrer"&gt;Astro’s “Add Integrations” documentation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Let’s say we want to use React. First, we need to install the integration by running the following in &lt;a href="https://kinsta.com/knowledgebase/what-is-npm/" rel="noopener noreferrer"&gt;npm&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;astro&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;react&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that React has been integrated, we can create a React component. In our case, it will be the counter component at &lt;strong&gt;src/components/ReactCounter.tsx&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/** A counter written with React */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subtract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"counter"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;subtract&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;-&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;+&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"counter-message"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last but not least, we need to place the counter on our page with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;react&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../components/ReactCounter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;react&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;visible&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And voilà: Your React component has been integrated seamlessly into your site.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Deploy Astro Using Kinsta&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now it’s time to get our Astro site onto the web. Luckily, Kinsta is the &lt;a href="https://kinsta.com/application-hosting/" rel="noopener noreferrer"&gt;perfect host for a quick and painless deployment&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Start by creating a GitHub repository for your site’s files. If you’re not ready to use your own files, you can clone this &lt;a href="https://github.com/kinsta/hello-world-astro" rel="noopener noreferrer"&gt;Astro starter site template&lt;/a&gt; our team created.&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%2Fuploads%2Farticles%2Fpiaobl51203trnjbrt7u.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%2Fuploads%2Farticles%2Fpiaobl51203trnjbrt7u.png" alt="GitHub repo of Astro starter site template by Kinsta"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub repo of Astro starter site template by Kinsta&lt;/p&gt;

&lt;p&gt;Once your repo is ready, &lt;a href="https://my.kinsta.com/" rel="noopener noreferrer"&gt;log in to MyKinsta&lt;/a&gt;, select &lt;strong&gt;Applications&lt;/strong&gt; at the left, and then choose &lt;strong&gt;Application&lt;/strong&gt; from the purple &lt;strong&gt;Add service&lt;/strong&gt; dropdown.&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%2Fuploads%2Farticles%2F4q0ic14tye0r9l9o95xa.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%2Fuploads%2Farticles%2F4q0ic14tye0r9l9o95xa.png" alt="Add an application in MyKinsta"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add an application in MyKinsta&lt;/p&gt;

&lt;p&gt;The final step involves you supplying Kinsta with the details of your build and deployment.&lt;/p&gt;

&lt;p&gt;Most of what you’ll be asked, such as &lt;strong&gt;Process name&lt;/strong&gt; and &lt;strong&gt;Payment method&lt;/strong&gt;, will have obvious or simple answers. Note that you may leave the &lt;strong&gt;Start command&lt;/strong&gt; field empty if you choose; Kinsta will automatically assign &lt;code&gt;npm start&lt;/code&gt; as the command.&lt;/p&gt;

&lt;p&gt;If you’re unsure how to respond to any other prompt, refer to Kinsta’s documentation for &lt;a href="https://kinsta.com/docs/add-an-application/" rel="noopener noreferrer"&gt;field-specific guidance&lt;/a&gt; and &lt;a href="https://kinsta.com/docs/astro-static-site/" rel="noopener noreferrer"&gt;Astro deployment examples&lt;/a&gt;. You can also check out &lt;a href="https://docs.astro.build/en/guides/deploy/kinsta/" rel="noopener noreferrer"&gt;Astro’s own guide to deploying at Kinsta&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once you’ve finished entering your build’s details, click the &lt;strong&gt;Confirm payment method&lt;/strong&gt; button to initialize your build.&lt;/p&gt;

&lt;p&gt;And that’s it! You now have a live, fully functioning static site created with the Astro framework.&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%2Fuploads%2Farticles%2F8ylr2rnco6j5jgfx7vyq.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%2Fuploads%2Farticles%2F8ylr2rnco6j5jgfx7vyq.png" alt="A dark page with the Kinsta logo in white in the center above the words "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our live Astro homepage&lt;/p&gt;

&lt;p&gt;You can find your live URL and other deployment details under &lt;strong&gt;Deployments&lt;/strong&gt; in your MyKinsta account.&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%2Fuploads%2Farticles%2Fnwgj2btvyeityfzg8k8s.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%2Fuploads%2Farticles%2Fnwgj2btvyeityfzg8k8s.png" alt="The "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A successful Astro deployment&lt;/p&gt;

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

&lt;p&gt;Astro’s clear structure, simple syntax, and global components make building and running an application really easy. , Its lightweight nature and dual use of static and dynamic routing dramatically increase site responsiveness, while its capacity for cooperating with and alongside other JavaScript frameworks makes it all the more appealing to experienced coders.&lt;/p&gt;

&lt;p&gt;If your goal is to create a content-rich site that loads quickly, grants modular functionality, and provides both static and dynamic generation, then Astro could be the right choice for you.&lt;/p&gt;

&lt;p&gt;You can host your static website with &lt;a href="https://kinsta.com/application-hosting/" rel="noopener noreferrer"&gt;Kinsta’s Application Hosting for free&lt;/a&gt;, and if you like it, upgrade to our &lt;a href="https://kinsta.com/application-hosting/pricing/hobby-tier/" rel="noopener noreferrer"&gt;Hobby Tier&lt;/a&gt; plan.&lt;/p&gt;

&lt;p&gt;💡 What are your thoughts on the Astro static site generator? Have you used it on a project of your own? Let us know in the comments section below.&lt;/p&gt;

</description>
      <category>astro</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What Is a Static Website? The Absolute Beginner’s Guide</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Wed, 04 Oct 2023 16:00:00 +0000</pubDate>
      <link>https://dev.to/kinsta/what-is-a-static-website-the-absolute-beginners-guide-3pp0</link>
      <guid>https://dev.to/kinsta/what-is-a-static-website-the-absolute-beginners-guide-3pp0</guid>
      <description>&lt;p&gt;Trying to decide between a static website vs a dynamic website for your next project? We got you.&lt;/p&gt;

&lt;p&gt;In this series, we'll cover what static websites are, how they function, how they differ from dynamic websites, and the respective pros and cons of both.&lt;/p&gt;

&lt;p&gt;By the end, you should have a good idea of which approach might be the best fit for your project, as well as how you can get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Is a Static Website?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A static website is a website that serves pages using a fixed number of pre-built files composed of &lt;a href="https://kinsta.com/knowledgebase/what-is-html/"&gt;HTML&lt;/a&gt;, CSS, and &lt;a href="https://kinsta.com/knowledgebase/what-is-javascript/"&gt;JavaScript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A static website has no backend server-side processing and no database. Any “dynamic” functionality associated with the static site is performed on the client side, which means the code is executed in visitors’ browsers rather than on the server.&lt;/p&gt;

&lt;p&gt;In non-technical terms, this means that your hosting delivers the website files to visitors’ browsers exactly as those files appear on the server.&lt;/p&gt;

&lt;p&gt;What’s more, every single visitor gets the same static file delivered to their browsers, which means they’ll largely have the exact same experiences and see the exact same content.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How Do Static Websites Work?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We’ll go over how to make a static website in more depth later on, but the basic approach that most static sites use is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Choose how to build your site&lt;/strong&gt; – while you could just manually create your static HTML, CSS, and JavaScript files for very simple websites, many modern static websites will use some type of static site generator tool or &lt;a href="https://kinsta.com/topic/headless-cms/"&gt;headless CMS&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Set up your site&lt;/strong&gt; – you’ll build your site using your chosen tool. Unlike something like WordPress, you won’t control your site from a live production server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deploy your site&lt;/strong&gt; – this means that you move your site’s static files onto live hosting so that users can access them. You could use application hosting or you could deploy your HTML files directly to &lt;a href="https://kinsta.com/knowledgebase/what-is-a-cdn/"&gt;a content delivery network (CDN)&lt;/a&gt;. Because your static site doesn’t require a database or server-side processing, there’s no need to store it on a single web server.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Examples of Static Websites and Tools&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When looking at a website, there’s no hard and fast rule to tell whether it’s static or dynamic. Instead, it’s more helpful to look at examples of tools that help you build and manage static websites.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EACdSKn3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7z46vh96q2pm1a0uzcwj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EACdSKn3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7z46vh96q2pm1a0uzcwj.jpg" alt="Hugo is a popular example of a static site generator." width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hugo is a popular example of a static site generator.&lt;/p&gt;

&lt;p&gt;Here are some of the most popular static website examples when it comes to software for creating static websites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kinsta.com/docs/jekyll-static-site-example/"&gt;Jekyll&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kinsta.com/blog/hugo-static-site/"&gt;Hugo&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kinsta.com/blog/gatsby-wordpress/"&gt;Gatsby&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://getpelican.com/"&gt;Pelican&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kinsta.com/blog/astro-js/"&gt;Astro&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kinsta.com/blog/eleventy/"&gt;Eleventy (11ty)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://getnikola.com/"&gt;Nikola&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://getpublii.com/"&gt;Publii&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these tools let you create static websites, but they go about it in very different ways. For example, Publii gives you a code-free desktop interface, while some other tools require you to use the command line.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Build a Static Website&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you think the advantages of building a static website might make it a good fit for your next project, here’s a quick guide on how to create a static website.&lt;/p&gt;

&lt;p&gt;We’re intentionally keeping this guide high level so that you can adapt it to your own use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Choose a Static Site Generator or CMS&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To start, you’ll want to choose a static site generator or a content management system that allows you to deploy a static site.&lt;/p&gt;

&lt;p&gt;If you have the technical knowledge, you can always create a static site from scratch using your own HTML, &lt;a href="https://kinsta.com/blog/css-best-practices/"&gt;CSS&lt;/a&gt;, and JavaScript, along with your &lt;a href="https://kinsta.com/blog/free-html-editor/"&gt;favorite HTML editor software&lt;/a&gt;. However, this can quickly become unwieldy as your site grows and you may or may not have &lt;a href="https://kinsta.com/blog/learn-html/"&gt;the technical knowledge to do everything from scratch&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A static site generator gives you a simpler way to build your static site. It will also make it easier to update your site in the future.&lt;/p&gt;

&lt;p&gt;Rather than needing to edit every single HTML file when you make a change (such as adding a new item to your navigation menu), the static site generator can help you deploy new versions of all your site’s files that reflect the changes.&lt;/p&gt;

&lt;p&gt;Here are some popular static site generators that you can consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://jekyllrb.com/"&gt;&lt;strong&gt;Jekyll&lt;/strong&gt;&lt;/a&gt; – one of the most popular open-source static website generators. Can work for a variety of sites and supports blogging. We have a whole post on &lt;a href="https://kinsta.com/blog/jekyll-static-site/"&gt;how to create a static site with Jekyll&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gohugo.io/"&gt;&lt;strong&gt;Hugo&lt;/strong&gt;&lt;/a&gt; – another popular open-source generator that can work for all different types of sites. We also have a post &lt;a href="https://kinsta.com/blog/hugo-static-site/"&gt;on how to create a static site with Hugo&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;WordPress + a static site generator plugin&lt;/strong&gt; – you can use WordPress to build your site but then deploy it as a static HTML site using your preferred static site generator plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more options, check out our &lt;a href="https://kinsta.com/blog/static-site-generator/"&gt;post with the top static site generators&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Build Your Website&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once you’ve chosen your preferred tool, you’ll use that tool to build your website.&lt;/p&gt;

&lt;p&gt;How that works will depend on which tool you choose, so there’s no single guide that will apply to all static site generators.&lt;/p&gt;

&lt;p&gt;If you’re coming from a WordPress background, using WordPress itself as a static site generator offers one of the simplest ways to get your toes wet and create your first static site.&lt;/p&gt;

&lt;p&gt;Here’s an example of what it might look like to build a static website with WordPress:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kinsta.com/blog/build-wordpress-site-offline/"&gt;&lt;strong&gt;Create a local WordPress site using DevKinsta&lt;/strong&gt;&lt;/a&gt;. This will not be the site that your visitors actually interact with – it’s just where you’ll manage your content and website design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Set up your site using your favorite design tool&lt;/strong&gt;. You could use &lt;a href="https://kinsta.com/blog/gutenberg-wordpress-editor/"&gt;the native WordPress block editor&lt;/a&gt; or you could use &lt;a href="https://kinsta.com/blog/wordpress-page-builders/"&gt;your favorite page builder plugin&lt;/a&gt; such as &lt;a href="https://kinsta.com/blog/divi-vs-elementor/"&gt;Elementor or Divi&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install a static site generator plugin&lt;/strong&gt;. This is what you’ll use to deploy your static website in the next step. Popular options include &lt;a href="https://wordpress.org/plugins/simply-static/"&gt;Simply Static&lt;/a&gt; and &lt;a href="https://wp2static.com/"&gt;WP2Static&lt;/a&gt;, though there are also newer alternatives such as &lt;a href="https://wordpress.org/plugins/staatic/"&gt;Staatic&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EJf-8ZTR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rruun3lb2goji1kh3mrb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EJf-8ZTR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rruun3lb2goji1kh3mrb.jpg" alt="The Simply Static plugin lets you use WordPress as a static site generator." width="800" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Simply Static plugin lets you use WordPress as a static site generator.&lt;/p&gt;

&lt;p&gt;Or another option would be to &lt;a href="https://kinsta.com/blog/gatsby-wordpress/"&gt;pair WordPress with Gatsy using GraphQL&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Deploy Your Website to Hosting&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once you’ve built your website, you need to “deploy” it to your hosting. Essentially, this means you need a way to get the static HTML files from your static site generator to your live hosting environment.&lt;/p&gt;

&lt;p&gt;There are a couple of different routes you can take here.&lt;/p&gt;

&lt;p&gt;One approach is to set up some type of automatic/continuous deployment using &lt;a href="https://kinsta.com/knowledgebase/what-is-github/"&gt;GitHub&lt;/a&gt;. You store your site’s files in a GitHub bucket. Then, whenever you push a new version of your site to GitHub, GitHub notifies your server and your server automatically deploys the new version of your site.&lt;/p&gt;

&lt;p&gt;For example, pushing new files to GitHub might automatically trigger a process like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When you make a change in GitHub, it automatically notifies your server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your web server pulls the latest files from GitHub and runs a Hugo build.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your server moves the files into the live site environment.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For another Git-based option, some people also like to &lt;a href="https://kinsta.com/blog/github-pages/"&gt;use GitHub pages for static websites&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As an alternative approach, some people also like to deploy directly to a CDN rather than using any type of web server. This approach might look something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You upload your site’s files to some type of online storage environment. Many tools can do this automatically or via the command line.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You set up a CDN to pull from that storage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you publish new files to your storage, the CDN will automatically start pulling in those new files.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your tool doesn’t offer any special features to simplify deploying your site, you would need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Generate your site’s static HTML files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manually upload those files to your static website hosting service, such as &lt;a href="https://kinsta.com/application-hosting/"&gt;Kinsta’s Application Hosting service&lt;/a&gt; (which offers &lt;a href="https://kinsta.com/docs/static-site-hosting/"&gt;support for static website hosting&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Should You Use a Static Website As Your Next Project?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Whether or not a static website is a good fit for your next project depends on the purpose of your website and your own knowledge level.&lt;/p&gt;

&lt;p&gt;As such, there’s no single one-size-fits-all answer here.&lt;/p&gt;

&lt;p&gt;Instead, let’s go through some situations when it might or might &lt;em&gt;not&lt;/em&gt; make sense to use a static website.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;When a Static Website Might Make Sense&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A static website works best for websites where all visitors see the same content and the content doesn’t change very often – especially for smaller websites with not a lot of content.&lt;/p&gt;

&lt;p&gt;Here are some types of websites that can work very well with the static approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kinsta.com/blog/portfolio-website/"&gt;Portfolio websites&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Basic business brochure websites&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resume websites&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simple blogs that don’t publish that often&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation content/knowledge bases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kinsta.com/blog/wordpress-landing-page-plugins/"&gt;Landing pages&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These types of websites are able to achieve all of the benefits of the static approach but with very few tradeoffs.&lt;/p&gt;

&lt;p&gt;For example, you’re unlikely to need to personalize a basic business brochure website, so you’re not “losing” any functionality by using the static approach.&lt;/p&gt;

&lt;p&gt;Similarly, these types of sites don’t change very often, so you won’t need to worry about constantly redeploying your static pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;When a Dynamic Website Might Make Sense&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To start, dynamic websites are generally always the best choice for situations where you need the ability to personalize the site experience, such as &lt;a href="https://kinsta.com/blog/ecommerce-platforms/"&gt;ecommerce stores&lt;/a&gt;, &lt;a href="https://kinsta.com/blog/create-a-membership-website/"&gt;membership websites&lt;/a&gt;, &lt;a href="https://kinsta.com/blog/wordpress-lms-plugins/"&gt;online courses&lt;/a&gt;, and so on.&lt;/p&gt;

&lt;p&gt;Basically, if you want users to be able to see different content on a page, you’ll typically want to use a dynamic website.&lt;/p&gt;

&lt;p&gt;While there are ways to build the aforementioned types of websites using a static website, the tradeoffs that you have to make usually aren’t worth it, which is why a dynamic website might be a better choice.&lt;/p&gt;

&lt;p&gt;Dynamic websites can also often make more sense for content-heavy sites, especially sites with lots of taxonomies and other methods of organization&lt;/p&gt;

&lt;p&gt;Similarly, if you’re regularly publishing new content all the time, that might be a reason to go with a dynamic website.&lt;/p&gt;

&lt;p&gt;For example, a personal blog where you only publish 1 new post every 2 weeks might be fine as a static website, but &lt;a href="https://kinsta.com/blog/how-to-monetize-a-blog/"&gt;a monetization-focused blog&lt;/a&gt; that’s publishing 5 new posts every day will probably be better as a dynamic website.&lt;/p&gt;

&lt;p&gt;💡Get all your &lt;a rel="noopener noreferrer nofollow" href="https://kinsta.com/application-hosting/pricing/"&gt;applications&lt;/a&gt;, &lt;a rel="noopener noreferrer nofollow" href="https://kinsta.com/database-hosting/pricing/"&gt;databases&lt;/a&gt;, and &lt;a rel="noopener noreferrer nofollow" href="https://kinsta.com/wordpress-hosting/pricing/"&gt;WordPress sites&lt;/a&gt; online and under one roof.&lt;/p&gt;

&lt;p&gt;Our feature-packed, high-performance cloud platform includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Easy setup and management in the MyKinsta dashboard&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;24/7 expert support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The best Google Cloud Platform hardware and network, powered by Kubernetes for maximum scalability&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An enterprise-level Cloudflare integration for speed and security&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Global audience reach with up to 35 data centers and 260 PoPs worldwide&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get started with a free trial of our &lt;a href="https://kinsta.com/application-hosting/pricing/"&gt;Application Hosting&lt;/a&gt; or &lt;a href="https://kinsta.com/database-hosting/pricing/"&gt;Database Hosting&lt;/a&gt;. Explore our &lt;a href="https://kinsta.com/wordpress-hosting/pricing/"&gt;plans&lt;/a&gt; or &lt;a href="https://kinsta.com/contact-us/"&gt;talk to sales&lt;/a&gt; to find your best fit.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>website</category>
    </item>
    <item>
      <title>Why Your Site's Slow: The Cookie Problem &amp; How to Fix It</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Wed, 27 Sep 2023 16:00:00 +0000</pubDate>
      <link>https://dev.to/kinsta/why-your-sites-slow-the-cookie-problem-how-to-fix-it-4c2h</link>
      <guid>https://dev.to/kinsta/why-your-sites-slow-the-cookie-problem-how-to-fix-it-4c2h</guid>
      <description>&lt;p&gt;Is your website feeling a bit slow? Using up more data? Often, 'cookies' are to blame. They're useful, but too many attached to your site can drag it down.&lt;/p&gt;

&lt;p&gt;Good news: There's a simple fix. Using cookie-free domains can speed things up. If you're using WordPress, this guide's for you.&lt;/p&gt;

&lt;p&gt;Let's understand how domains and cookies work together – both the good and bad.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;How To Use Cookie-Free Domains&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;The general idea of a cookie-free domain is to deliver static content without delivering cookies. Though creating a separate static domain or subdomain is the most direct way to do this, it’s also possible with CDNs and a couple of WordPress tricks.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Create a Separate, Cookie-Free Domain&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With this method, you’ll create a separate domain for hosting your website’s static components, such as images and CSS.&lt;/p&gt;

&lt;p&gt;While you can register an entirely separate domain name, it’s usually easier and more cost-effective to create a subdomain of your existing domain name. Most cookie-free domains simply use a static prefix (e.g., “&lt;a href="http://static.yourdomain.com" rel="noopener noreferrer"&gt;&lt;strong&gt;static.yourdomain.com&lt;/strong&gt;&lt;/a&gt;”) as their subdomain.&lt;/p&gt;

&lt;p&gt;Note that this will only work if the “www” version of your domain (e.g., “&lt;a href="http://www.yourdomain.com" rel="noopener noreferrer"&gt;&lt;strong&gt;www.yourdomain.com&lt;/strong&gt;&lt;/a&gt;”) is the root domain in your website’s &lt;a href="https://kinsta.com/knowledgebase/wordpress-files/" rel="noopener noreferrer"&gt;root file&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To make the subdomain cookieless, you’d normally have to find and edit your &lt;a href="https://kinsta.com/knowledgebase/wordpress-htaccess-file/" rel="noopener noreferrer"&gt;.htaccess file&lt;/a&gt; directly using special code. However, as we’ll see later, it’s much easier to simply reconfigure your WordPress site or use a plugin.&lt;/p&gt;

&lt;p&gt;However you configure your cookie-free subdomain, you can upload static components, such as your CSS components, images, text, and JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Use a Content Delivery Network (CDN)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Using a content delivery network or &lt;a href="https://kinsta.com/docs/kinsta-cdn/" rel="noopener noreferrer"&gt;CDN&lt;/a&gt; is an extremely convenient way to use cookie-free domains.&lt;/p&gt;

&lt;p&gt;Here, rather than having to create separate subdomains and edit configuration files, you can simply tell your CDN to ignore and strip cookies from the response headers of your static components. That may sound a bit complicated, but it’s actually a simple feature in many CDNs.&lt;/p&gt;

&lt;p&gt;Note that not every CDN provides this functionality. As a result, it’s generally better to change your website’s configuration unless you’re already using a CDN that allows you to disable cookies.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Reconfigure Your WordPress Site&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you’re using WordPress, you’re in luck: All it takes to designate a cookie-free domain is to update a couple of lines in your &lt;a href="https://kinsta.com/blog/wp-config-php/" rel="noopener noreferrer"&gt;wp-config.php file&lt;/a&gt;. Skip ahead to the next section (Configuring WordPress to Use Cookie-Free Domains) for complete instructions.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Use a WordPress Plugin&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Another easy WordPress option is to use a plugin for creating static versions of WordPress websites.&lt;/p&gt;

&lt;p&gt;One popular plugin for doing this is &lt;a href="https://wp2static.com/" rel="noopener noreferrer"&gt;WP2Static&lt;/a&gt; (literally “WordPress-to-Static”). After installing the plugin, simply open it in your WordPress dashboard and configure the settings to export your website to a static version:&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%2Fuploads%2Farticles%2F8lrhjfz8crby9kgr9ls4.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%2Fuploads%2Farticles%2F8lrhjfz8crby9kgr9ls4.png" alt="WP2Static"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WP2Static&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Configuring WordPress to Use Cookie-Free Domains&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As mentioned above, WordPress offers an easy way to implement cookie-free domains. The process boils down to a few simple steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Adding an alternate subdomain and associated DNS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Telling WordPress which domain will serve up static assets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updating existing WordPress database records to reflect this new address&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Kinsta customers can use the &lt;a href="https://kinsta.com/mykinsta/" rel="noopener noreferrer"&gt;MyKinsta&lt;/a&gt; dashboard to accomplish some of these tasks. Many other WordPress users will be able to do the same in &lt;a href="https://kinsta.com/knowledgebase/what-is-cpanel/" rel="noopener noreferrer"&gt;cPanel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We’ll cover both below.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Using MyKinsta To Set up a Cookie-Free Domain&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Kinsta customers can associate subdomains (or completely different domains) with a WordPress instance within the MyKinsta dashboard. Many customers will also use MyKinsta’s tools to configure DNS for those domains.&lt;/p&gt;

&lt;p&gt;In this example, we’ll create a cookie-free domain at &lt;a href="http://static.example.com" rel="noopener noreferrer"&gt;&lt;strong&gt;static.example.com&lt;/strong&gt;&lt;/a&gt; for our website already up and running at &lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;&lt;strong&gt;www.example.com&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 1. Create a Subdomain in MyKinsta&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;If you initially established your WordPress site at Kinsta using the wildcard option with its domain name (like: &lt;strong&gt;*.&lt;/strong&gt;&lt;a href="http://example.com" rel="noopener noreferrer"&gt;&lt;strong&gt;example.com&lt;/strong&gt;&lt;/a&gt;), you are already set to support any subdomain name. If not, you can add the new domain for cookie-free content like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;WordPress Sites&lt;/strong&gt; on the left-hand menu.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on the name of your WordPress site.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Domains&lt;/strong&gt; on the left-hand menu.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the &lt;strong&gt;Add Domain&lt;/strong&gt; button.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2Fuploads%2Farticles%2Fy9kae5wbom6els319kbz.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%2Fuploads%2Farticles%2Fy9kae5wbom6els319kbz.png" alt="Adding a subdomain within MyKinsta."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding a subdomain within MyKinsta.&lt;/p&gt;

&lt;p&gt;In the following dialog:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Type the name of your cookie-free domain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the &lt;strong&gt;Add Domain&lt;/strong&gt; button.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2Fuploads%2Farticles%2Fbzg7ljcfsdphy4on4c8j.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%2Fuploads%2Farticles%2Fbzg7ljcfsdphy4on4c8j.png" alt="Specifying the new subdomain within MyKinsta."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Specifying the new subdomain within MyKinsta.&lt;/p&gt;

&lt;p&gt;Next, your new static domain will need a DNS record pointing to your existing website. If you manage DNS for your domains through a third-party provider, you will use their tools to do that. If your DNS is provided by us, configure your new domain in MyKinsta like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;DNS&lt;/strong&gt; on the left-hand menu of the MyKinsta home page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the &lt;strong&gt;DNS Management&lt;/strong&gt; page, scroll down to the &lt;strong&gt;DNS Records&lt;/strong&gt; block and click the &lt;strong&gt;Add DNS Record&lt;/strong&gt; button.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We recommend adding your new subdomain to DNS as a CNAME record, allowing you to rely on just the second-level domain name for associations with IP addresses. Below, we are adding a CNAME record for &lt;strong&gt;static&lt;/strong&gt; that points to &lt;a href="http://example.com" rel="noopener noreferrer"&gt;&lt;strong&gt;example.com&lt;/strong&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1cbbumlcabu5qawi302.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%2Fuploads%2Farticles%2Fz1cbbumlcabu5qawi302.png" alt="Creating a CNAME record in MyKinsta DNS management."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating a CNAME record in MyKinsta DNS management.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 2. Disable Cookies on Your Static Subdomain&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Now we’ll edit your WordPress site’s &lt;strong&gt;wp-config.php&lt;/strong&gt; file so that assets within the &lt;code&gt;wp-content&lt;/code&gt; folder are served up from the “static” domain and cookies are delivered only via the “www” address.&lt;/p&gt;

&lt;p&gt;Most Kinsta customers will use an FTP/SFTP client to login to their WordPress site and download &lt;strong&gt;wp-config.php&lt;/strong&gt; to their desktop for editing:&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%2Fuploads%2Farticles%2F8k26t7s8rttc1s2emftf.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%2Fuploads%2Farticles%2F8k26t7s8rttc1s2emftf.png" alt="Downloading the wp-config.php file to the desktop."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Downloading the wp-config.php file to the desktop.&lt;/p&gt;

&lt;p&gt;Use a text editor to add the following lines to the &lt;strong&gt;wp-config.php&lt;/strong&gt; file (replacing the example domains with your own own):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"WP_CONTENT_URL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"https://static.example.com/wp-content"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"COOKIE_DOMAIN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"www.example.com"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After saving the file, upload it to your WordPress site, replacing the previous version.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 3. Redirect Existing Assets to the Subdomain&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The steps above will allow cookies to be handed out when browsers load content like pages and blog posts from the “www” address, but will cause content like media uploads and assets like JavaScript, CSS and fonts within themes to be associated with the “static” domain.&lt;/p&gt;

&lt;p&gt;However, your website may already have content that contains links to those assets at the “www” address. You can clean that up with a little search-and-replace in the WordPress database itself.&lt;/p&gt;

&lt;p&gt;Always &lt;a href="https://kinsta.com/blog/backup-wordpress-site/" rel="noopener noreferrer"&gt;back up your WordPress site&lt;/a&gt; before working in the database. After that is done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;WordPress Sites&lt;/strong&gt; on the left-hand menu of the MyKinsta dashboard.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on the name of your WordPress site.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Domains&lt;/strong&gt; on the left-hand menu.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the &lt;strong&gt;Site Information&lt;/strong&gt; page, scroll down to the Database Access block. (You can copy database username and password information here if needed.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the &lt;strong&gt;Open phpMyAdmin&lt;/strong&gt; link.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Login to your WordPress database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the &lt;strong&gt;SQL&lt;/strong&gt; tab.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2Fuploads%2Farticles%2Fzlgn972hy2hqetaq8m91.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%2Fuploads%2Farticles%2Fzlgn972hy2hqetaq8m91.png" alt="Updating content in the WordPress database using phpMyAdmin."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Running an SQL query to update asset links in WordPress content.&lt;/p&gt;

&lt;p&gt;Run the following command to be sure that any asset links within your existing posts are directed to your cookie-free subdomain (again, being sure to replace the domains with your own):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;wp_posts&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;post_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'www.example.com/wp-content/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' static.example.com/wp-content/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ve now successfully configured a cookie-free domain in WordPress with the help of MyKinsta. Use this domain to host any static content for which you don’t want to send &lt;a href="https://kinsta.com/blog/wordpress-cookies-php-sessions/" rel="noopener noreferrer"&gt;WordPress cookies&lt;/a&gt; and use your regular domain for everything else.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Using cPanel To Set up a Cookie-Free Domain&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here are the steps to accomplish what we did above in MyKinsta using cPanel or one of the popular &lt;a href="https://kinsta.com/blog/cpanel-alternatives/" rel="noopener noreferrer"&gt;cPanel alternatives&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 1. Create a Subdomain in cPanel&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Navigate to the &lt;strong&gt;Domains&lt;/strong&gt; section of the cPanel main page. In the &lt;strong&gt;Subdomains&lt;/strong&gt; tool, simply create a subdomain connected to the top-level domain of your current WordPress site.&lt;/p&gt;

&lt;p&gt;These settings can be seen below to create the subdomain &lt;a href="http://static.example.com" rel="noopener noreferrer"&gt;&lt;strong&gt;static.example.com&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyhm0a0xl6nqe3igg9nu.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%2Fuploads%2Farticles%2Fjyhm0a0xl6nqe3igg9nu.png" alt="Creating a subdomain in cPanel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating a subdomain in cPanel&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 2. Configure the Subdomain as Static in cPanel&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;With your new static subdomain ready to go, it’s time to make it live up to its name by making it serve static content in WordPress.&lt;/p&gt;

&lt;p&gt;We’ll do this by editing your WordPress site’s &lt;strong&gt;wp-config.php&lt;/strong&gt; file. The easiest way to access this file is in cPanel’s &lt;strong&gt;File Manager&lt;/strong&gt; tool.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;File Manager&lt;/strong&gt;, navigate to your website’s &lt;strong&gt;public_html folder&lt;/strong&gt; and select &lt;strong&gt;wp-config.php&lt;/strong&gt; (1). Then, select the &lt;strong&gt;Edit&lt;/strong&gt; option (2) to edit the file.&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%2Fuploads%2Farticles%2Fyk41t8nmglhgwljit0qa.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%2Fuploads%2Farticles%2Fyk41t8nmglhgwljit0qa.png" alt="Locating the wp-config.php file in the cPanel File Manager tool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Locate the wp-config.php file&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;wp-config.php&lt;/strong&gt; file, simply add the following lines (being sure to replace the domains with your own!):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"WP_CONTENT_URL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"https://static.example.com/wp-content"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"COOKIE_DOMAIN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"www.example.com"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click “&lt;strong&gt;Save Changes&lt;/strong&gt;.”&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 3. Redirect Existing Posts to the Subdomain&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Finally, you’ll need to redirect your existing posts to the new static subdomain. But first, be sure to &lt;a href="https://kinsta.com/blog/backup-wordpress-site/" rel="noopener noreferrer"&gt;back up your WordPress site&lt;/a&gt; just in case it doesn’t function properly after.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Database&lt;/strong&gt; section of cPanel, open the &lt;strong&gt;PhpMySQL&lt;/strong&gt; tool. Select your site’s database and then its &lt;strong&gt;_posts&lt;/strong&gt; table.&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;SQL&lt;/strong&gt; tab of the &lt;strong&gt;_posts&lt;/strong&gt; table. Run the following command to verify that your post URLs are directed to your cookie-free subdomain (again, being sure to replace the domains with your own):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;wp_posts&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;post_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'www.example.com/wp-content/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' static.example.com/wp-content/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fuploads%2Farticles%2Fjkjq6avqdkhn5skkm0qd.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%2Fuploads%2Farticles%2Fjkjq6avqdkhn5skkm0qd.png" alt="Redirecting existing posts to the new static subdomain"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redirecting existing posts to the new static subdomain&lt;/p&gt;

&lt;p&gt;And that’s it! You’ve now set up a cookie-free domain in WordPress with the help of cPanel. Use the cookie-free domain for static content like images, CSS, JavaScript, and fonts, while allowing cookies on your site’s primary domain.&lt;/p&gt;

&lt;p&gt;Setting up cookie-free domains in WordPress is beneficial. However, only a &lt;a href="https://kinsta.com/wordpress-hosting/" rel="noopener noreferrer"&gt;managed WordPress host&lt;/a&gt; like Kinsta can take full advantage of these benefits.&lt;/p&gt;

&lt;p&gt;With convenient tools for &lt;a href="https://kinsta.com/docs/remove-set-cookie-headers/" rel="noopener noreferrer"&gt;removing set-cookie headers&lt;/a&gt; and &lt;a href="https://kinsta.com/docs/db-access/" rel="noopener noreferrer"&gt;direct database access&lt;/a&gt; to redirect posts to a static subdomain, it’s never been easier to use cookie-free domains. Kinsta’s &lt;a href="https://kinsta.com/apm-tool/" rel="noopener noreferrer"&gt;APM tools&lt;/a&gt; and other performance-monitoring features can also help you track the results.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>cookie</category>
      <category>website</category>
    </item>
    <item>
      <title>MEAN Stack Explained</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Tue, 26 Sep 2023 18:46:18 +0000</pubDate>
      <link>https://dev.to/kinsta/mean-stack-explained-lgj</link>
      <guid>https://dev.to/kinsta/mean-stack-explained-lgj</guid>
      <description>&lt;p&gt;The MEAN stack is an open-source collection of JavaScript technologies that’s gained significant popularity. It makes it easy to build complex, full-stack web applications and is an excellent option for front and backend development.&lt;/p&gt;

&lt;p&gt;This article explores the MEAN stack’s components and use cases, highlighting why it’s an intelligent choice for your full-stack applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Is the MEAN Stack Right for You?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The MEAN acronym comes from its four key components: MongoDB, Express.js, Angular, and Node.js. Each component plays a vital role in building flexible and efficient JavaScript applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;MongoDB&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://kinsta.com/knowledgebase/what-is-mongodb/"&gt;MongoDB&lt;/a&gt; is a popular NoSQL database that stores data as binary JSON (&lt;a href="https://kinsta.com/blog/mongodb-create-database/#documents"&gt;BSON&lt;/a&gt;) documents. Its extensive flexibility and scalability make it well-suited for applications that store large and complex data. It’s also cross-platform, allowing you to use a single language across the entire stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Express.js&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://kinsta.com/knowledgebase/what-is-express-js/"&gt;Express.js&lt;/a&gt; is a flexible, lightweight framework for the backend development of Node.js applications. It acts as middleware to ensure smooth interaction between the client and the database. It also offers robust routing capabilities and a default error handler.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Angular&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://kinsta.com/blog/angular-vs-vue/#what-is-angular"&gt;Angular&lt;/a&gt; is a JavaScript framework for frontend development. It provides features like two-way data binding and dependency injection to enable dynamic views, simplifying how you build complex and interactive user interfaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Node.js&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://kinsta.com/knowledgebase/what-is-node-js/"&gt;Node.js&lt;/a&gt; is an open-source, cross-platform JavaScript runtime environment. It enables server-side JavaScript execution and provides an event-driven, non-blocking I/O architecture. Its asynchronous nature means it can handle multiple concurrent requests without blocking the execution of other code.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Advantages of the MEAN Stack&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The MEAN stack makes it easy to build full-stack, real-time web applications. Let’s go over some of its most compelling benefits.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Full-Stack JavaScript&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;MEAN’s primary advantage is that it lets you build full-stack applications using a single language, allowing you to reuse code and keep it structurally and syntactically consistent. Reusability can significantly accelerate the development process so you can focus on more complex tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scalability&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;MEAN is also exceptionally scalable, making it a popular choice for building large-scale web applications. The asynchronous architecture of Node.js enables easy horizontal scaling, and &lt;a href="https://kinsta.com/blog/mongodb-sharding/"&gt;MongoDB supports sharding&lt;/a&gt;. You can distribute your data storage across numerous servers and add more servers to your clusters as demand increases.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Community and Ecosystem&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As an open-source tech stack, MEAN has a thriving developer community contributing to its ongoing development and maintenance. This culture of collaboration also gives it a well-rounded support system and a low barrier to entry, with many learning resources to help you get started.&lt;/p&gt;

&lt;p&gt;In addition, MEAN has a wealth of libraries, frameworks, and other tools within the Node.js package manager (npm). This rich ecosystem enables you to integrate features easily into your application without building them from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;MEAN Stack Limitations&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;While MEAN does offer several advantages, it may not always be the right choice for certain applications. There are a few drawbacks to keep in mind.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Limited Support for Relational Databases&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Relational or SQL databases store data in tables using a rigid schema to ensure data integrity and structure. However, MongoDB is a NoSQL database that stores data in the more flexible BSON format.&lt;/p&gt;

&lt;p&gt;Developers wishing to use relational databases with the MEAN stack must integrate additional tools. However, it makes the application more complex, which can detract from its maintainability. Therefore, MEAN may not be ideal for applications that require highly structured data with optimal integrity.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Performance Issues&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Unlike how it handles other tasks, Node.js executes JavaScript code one task at a time. While this single-threaded model has its advantages, it can also lead to bottlenecks when dealing with CPU-intensive tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Steep Learning Curve&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Despite their supportive communities and resources, Angular and MongoDB can be difficult for new developers to learn.&lt;/p&gt;

&lt;p&gt;Angular is a complex and verbose framework with advanced features that require significant time and effort to comprehend. Developers may also need to contend with its continuous evolution and regular updates while they navigate the framework.&lt;/p&gt;

&lt;p&gt;Meanwhile, developers with more experience using traditional SQL databases may find it challenging to adapt to MongoDB’s flexibility. Because MongoDB doesn’t require a strict schema, developers may need to learn new techniques and syntax for optimizing indexes and managing transactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Use Cases for the MEAN Stack&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Despite these minor weaknesses, the MEAN stack is ideal for developing a wide range of applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Single-Page Applications&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;MEAN is great for building single-page applications (SPAs), such as ecommerce applications, content management systems (CMSs), and social networking applications.&lt;/p&gt;

&lt;p&gt;SPAs must supply dynamic and (often) personalized updates without requiring end users to reload the page. &lt;a href="https://kinsta.com/blog/angular-component-libraries/"&gt;Angular&lt;/a&gt; simplifies this dynamic view creation through its component-based architecture, templating, and two-way data binding. You can customize your UI to your users’ preferences and update it in real time based on their interactions with the page.&lt;/p&gt;

&lt;p&gt;Furthermore, you can combine Angular with Express.js to enhance the user experience. While Angular dynamically renders the UI, Express.js provides the routing and middleware to handle client requests and communicate with the database or external services.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Real-Time Web Applications&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The MEAN stack is also ideal for building real-time web applications, such as gaming sites, chat applications, and collaboration tools. Node.js supports real-time data processing through its asynchronous I/O model. It also provides web sockets to enable seamless data transfer between the client and server without needing multiple &lt;a href="https://kinsta.com/knowledgebase/javascript-http-request/"&gt;HTTP requests&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This persistent connection enables applications to deliver live messages and updates. When a user sends a message in a chat application, and the server immediately broadcasts it to the intended recipient, they experience the all-but-invisible benefit of the persistent connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Data-Intensive Applications&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;MEAN is also well-equipped to handle the demands of data-intensive processes that drive applications like ecommerce platforms and finance software.&lt;/p&gt;

&lt;p&gt;Node.js is an excellent option for processing and managing large amounts of data without impacting performance. Meanwhile, MongoDB is exceptional at handling large and complex data sets. It can also make read-and-write operations to the database, which are crucial functions for applications that must store, update, and retrieve data quickly.&lt;/p&gt;

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

&lt;p&gt;The MEAN stack is a powerful solution for building robust full-stack applications. It allows you to use a single language to develop the frontend with Angular and the backend using Node.js. MongoDB helps you handle complex data, and Node.js establishes an asynchronous runtime environment for enhanced performance and responsiveness.&lt;/p&gt;

&lt;p&gt;From SPAs to chat applications to e-commerce platforms, MEAN lets you build highly responsive and flexible applications that can scale to meet traffic and data demands. It also has a large community of active users and numerous libraries and tools to help you get started.&lt;/p&gt;

&lt;p&gt;With Kinsta, you can easily deploy MEAN stack applications, providing a &lt;a href="https://kinsta.com/blog/what-is-paas/"&gt;Platform as a Service&lt;/a&gt; to ship your application without needing to manage infrastructure. You can deploy changes to your application at every push to your &lt;a href="https://kinsta.com/blog/advanced-git/"&gt;Git&lt;/a&gt; repository.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Use Pseudocode for a more efficient (and headache-free) coding</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Wed, 09 Aug 2023 16:45:00 +0000</pubDate>
      <link>https://dev.to/kinsta/use-pseudocode-for-a-more-efficient-and-headache-free-coding-2o5e</link>
      <guid>https://dev.to/kinsta/use-pseudocode-for-a-more-efficient-and-headache-free-coding-2o5e</guid>
      <description>&lt;p&gt;Ever heard of Pseudocode? It's a combination of simple language and programming elements that helps you represent your code.&lt;/p&gt;

&lt;p&gt;Understanding it is a time-saving trick you can integrate into your process at any time - so you don't have to be stressed and frustrated when explaining your code to others.&lt;/p&gt;

&lt;p&gt;Here's more about Pseudocode, how it's used, and why it's an essential &lt;a href="https://kinsta.com/blog/web-development-tools/"&gt;tool for any developer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Is Pseudocode?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Pseudocode is a simplified way of explaining coding elements like algorithms, functions, or other processes, using a mix of everyday language and programming-like elements.&lt;/p&gt;

&lt;p&gt;It’s called “pseudo” code because it’s not actually executable. Instead, it’s a way for humans to understand and plan out the logic in coding — to describe the steps of a program in a way that’s easy for humans to understand, while still being detailed enough to be rapidly converted into a specific programming language.&lt;/p&gt;

&lt;p&gt;Here’s a simple example of pseudocode, in which we’re working out the basic logic to greet a visitor by name when they navigate to our site or app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PROCESS GreetUser
    INPUT userName
    DISPLAY "Hello, " + userName + "!"
END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the above pseudocode isn’t written with syntax from any actual language or framework. Instead, it uses simple, universally understandable language and programming elements — like &lt;code&gt;PROCESS&lt;/code&gt;, &lt;code&gt;DISPLAY&lt;/code&gt;, and &lt;code&gt;+&lt;/code&gt; — to stand in as syntax, making it simple for anyone to follow.&lt;/p&gt;

&lt;p&gt;That’s one of the powers of writing pseudocode: By laying the code’s intentions out in a common syntax, you can jump all programming and skill-based language barriers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Write Pseudocode&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Pseudocode's flexibility comes from its lack of specific syntax, which means there's no single correct way to write it. While languages like Pascal and Basic provide specific pseudocode rules, you can use any language or terminology, as long as it's universally understood and the logic is clear.&lt;/p&gt;

&lt;p&gt;Despite its open-ended nature, developers usually follow some basic pseudocode guidelines. Let's dive into these next.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Sequences&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;A sequence is a group of statements that are executed in a specific order. They’re used to perform or repeat a series of simple actions. Some familiar sequence commands commonly used in pseudocode include &lt;code&gt;INPUT&lt;/code&gt;, &lt;code&gt;SET&lt;/code&gt;, &lt;code&gt;PRINT&lt;/code&gt;, &lt;code&gt;READ&lt;/code&gt;, &lt;code&gt;DISPLAY&lt;/code&gt;, &lt;code&gt;SHOW&lt;/code&gt;, and &lt;code&gt;CALCULATE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here’s an example of pseudocode that uses some of these commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PROCESS CalculateCost
    INPUT price, quantity
    SET cost = price * quantity
    PRINT "The cost is: " + cost
END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pseudocode defines a process called CalculateCost that takes in a price and quantity, multiplies them together to calculate the cost, and then displays the result.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Conditionals&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Conditional statements allow a program to make decisions based on certain conditions, then direct the program to execute certain statements if a condition is met (or not met). &lt;code&gt;IF-ELSE&lt;/code&gt;, &lt;code&gt;IF-IF ELSE-ELSE&lt;/code&gt;, and &lt;code&gt;CASE&lt;/code&gt; statements are frequently utilized in pseudocode.&lt;/p&gt;

&lt;p&gt;Here’s an example showing an &lt;code&gt;IF-ELSE&lt;/code&gt; script in pseudocode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IF user = returning
    PRINT "Welcome back!"
ELSE
    PRINT "Welcome!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we’re describing a process that shows a “Welcome back!” message to users who have visited before, but shows only “Welcome!” to new users.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Iterations&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Iteration statements repeat a set of steps within a larger function or process. They’re often tasked to perform the same operation on multiple items in a list or to repeat a process until certain conditions are met.&lt;/p&gt;

&lt;p&gt;Iterations are useful for repeating a set of steps multiple times and can be implemented using various types of loops, including &lt;code&gt;FOR&lt;/code&gt;, &lt;code&gt;WHILE&lt;/code&gt;, and &lt;code&gt;DO-WHILE&lt;/code&gt; loops.&lt;/p&gt;

&lt;p&gt;Let’s look at some pseudocode that uses a &lt;code&gt;FOR&lt;/code&gt; loop to iterate through a list of numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PROCESS PrintWholeList
    INPUT listOfNumbers 
    FOR each number in listOfNumbers
    PRINT number
    END FOR
END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above pseudocode, our PrintWholeList process takes in a list of numbers and then iterates through the list, displaying each number on the screen. The &lt;code&gt;FOR&lt;/code&gt; loop allows the process to repeat the &lt;code&gt;PRINT&lt;/code&gt; command for each item in the list.&lt;/p&gt;

&lt;p&gt;Alternatively, we could utilize the common pseudocode to accomplish the same as our above loop. In pseudocode, it’s more common to use the keywords &lt;code&gt;REPEAT&lt;/code&gt; and &lt;code&gt;UNTIL&lt;/code&gt; in place of &lt;strong&gt;DO-WHILE&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PROCESS PrintWholeList
    INPUT listOfNumbers 
    SET counter = 0
    REPEAT
    PRINT listOfNumbers[counter]
    SET counter = counter + 1
    UNTIL counter = length of listOfNumbers
END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As shown here, we can switch out the names, keywords, and syntax pieces all we like. This is just one demonstration of pseudocode’s flexibility. The key is to ensure that the logic is stable while using names that are ubiquitous enough to be read by anyone.&lt;/p&gt;

&lt;p&gt;You can see some of these constructs used in the pseudocode examples we’ll work with later on.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Pseudocode Examples and Translations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here are some examples of pseudocode, along with their translations into executable code in various languages and frameworks.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;PHP&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;To start, let’s write some pseudocode that’s meant to mimic the logic of adding up all the numbers in a given list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PROCESS FindTotal
    INPUT listOfNumbers
    SET sum = 0
    FOR EACH number IN listOfNumbers
    SET sum = sum + number
    END FOR
    PRINT sum
END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our pseudocode logic follows these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Give the function a name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get the list of numbers from the end user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a variable called sum to house the numerical total as it gets calculated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Iterate through every number in the list one by one, adding each number to the sum’s total.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After all the numbers have been added, end the iteration (loop).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Display the final sum obtained from adding all the numbers together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End the function.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that we know the logic of our function, we can translate this pseudocode into any other language or framework. Let’s see what it might look like translated into &lt;a href="https://kinsta.com/knowledgebase/what-is-php/"&gt;PHP&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function findTotal($listOfNumbers) {
    $sum = 0;
    foreach ($listOfNumbers as $number) {
    $sum += $number;
    }
    echo $sum;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Node.js&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Next, let’s write some pseudocode we can use to check what the current time is for our visitors, then send them the appropriate greeting based on their time of day:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PROCESS TimedGreeting
    GET userTime
    IF userTime &amp;gt; 6:00 + &amp;lt; 12:00
    PRINT "Good morning!"
    ELSE IF userTime &amp;gt; 12:00 + &amp;lt; 18:00
    PRINT "Good afternoon!"
    ELSE
    PRINT "Good evening!"
END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our pseudocode logic follows these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Give the function a name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Find the user’s time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the user’s time is between 6:00 AM and 12:00 PM, show the message “Good morning!”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the user’s time is between 12:00 PM and 6:00 PM, show the message “Good afternoon!”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For any other time, show the message “Good evening!”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End the function.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Translated into &lt;a href="https://kinsta.com/knowledgebase/what-is-node-js/"&gt;Node.js&lt;/a&gt;, it might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function timedGreeting() {
    const userTime = new Date();
    if (userTime.getHours() &amp;gt; 6 &amp;amp;&amp;amp; userTime.getHours() &amp;lt; 12) {
    console.log('Good morning!');
    } else if (userTime.getHours() &amp;gt; 12 &amp;amp;&amp;amp; userTime.getHours() &amp;lt; 18) {
    console.log('Good afternoon!');
    } else {
    console.log('Good evening!');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Python&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;For our next example, let’s write some pseudocode to outline the logic for reversing a string (in this case, a sentence) that’s given to us by a user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PROCESS ReverseString
    INPUT string
    SET reversed_string = reverse of string
    PRINT "The reversed sentence is: ", reversed_string
END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our pseudocode logic follows these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Give the function a name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prompt the user for a string and accept what they provide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Store the value of the user’s string variable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Slice the stored string value to reverse it, and store the result in a new variable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Display the reversed string on the screen.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End the function.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When &lt;a href="https://kinsta.com/blog/python-commands/"&gt;translated to Python&lt;/a&gt;, it might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string = input("Enter a sentence: ")
reversed_string = string[::-1]
print("The reversed sentence is: ", reversed_string)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In some cases, your actual translated code will be shorter than your pseudocode. That’s fine. As long as your pseudocode’s logic is sound and your translated code functions as it should, you can disregard the discrepancies in length.&lt;/p&gt;

&lt;p&gt;💡 Got any other use-case idea for Pseudocode? Drop them below!&lt;/p&gt;

</description>
      <category>coding</category>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Laravel Caching Strategies Every Developer Wishes They Knew Sooner</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Wed, 02 Aug 2023 12:00:00 +0000</pubDate>
      <link>https://dev.to/kinsta/the-laravel-caching-strategies-every-developer-wishes-they-knew-sooner-3j94</link>
      <guid>https://dev.to/kinsta/the-laravel-caching-strategies-every-developer-wishes-they-knew-sooner-3j94</guid>
      <description>&lt;p&gt;Caching is essential for fast and efficient websites. Implementing the right caching strategy from the start is crucial to avoid slow APIs and page load times that can harm your SEO, user engagement, and conversion rates.&lt;/p&gt;

&lt;p&gt;There are several cache strategies available, and you can even create a custom strategy to fit your needs. Here are some popular caching strategies that you can implement in your Laravel project.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Laravel Caching Strategies&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;writeThrough&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In the &lt;strong&gt;writeThrough&lt;/strong&gt; strategy, the cache server sits between the requests and the database server, making every &lt;strong&gt;write&lt;/strong&gt; operation go through the cache server before going to the Database Server. Thus, the &lt;strong&gt;writeThrough&lt;/strong&gt; caching strategy is similar to the &lt;strong&gt;readThrough&lt;/strong&gt; strategy.&lt;/p&gt;

&lt;p&gt;You can implement this strategy with the Laravel cache with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;writeThrough&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$cacheData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Database Server is called from(after) the Cache Server.&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;storeToDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cachedData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$cacheData&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;storeToDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;writeBack (writeBehind)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This strategy is a more advanced way of implementing the &lt;strong&gt;writeThrough&lt;/strong&gt; strategy by adding writing operations delays.&lt;/p&gt;

&lt;p&gt;You can also call this the &lt;strong&gt;writeBehind&lt;/strong&gt; strategy because of the delay in time applied to the cache server before writing the data to the database server.&lt;/p&gt;

&lt;p&gt;You can implement this strategy with the Laravel cache with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$durationToFlush&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// (in minute)&lt;/span&gt;
 &lt;span class="nv"&gt;$tempDataToFlush&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;writeBack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;writeThrough&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;writeThrough&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$cacheData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;storeForUpdates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cacheData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$cacheData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Stores new data to temp Array for updating&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;storeForUpdates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nv"&gt;$tempData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="nv"&gt;$tempData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'duration'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMinutesInMilli&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$tempData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'data'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;array_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$tempDataToFlush&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Converts minutes to millisecond&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getMinutesInMilli&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="nv"&gt;$currentDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nv"&gt;$futureDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Carbon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Carbon&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;durationToFlush&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$futureDate&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Calls to update the Database Server.&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;updateDatabaseServer&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;tempDataToFlush&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;tempDataToFlush&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$index&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$obj&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$obj&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$obj&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;
            &lt;span class="nb"&gt;array_splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;tempDataToFlush&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;writeBack&lt;/strong&gt; method calls to the &lt;strong&gt;writeThrough&lt;/strong&gt; method, which stores the data to the cache server and a temporary array to be pushed later to the database server using the &lt;strong&gt;updateDatabaseServer&lt;/strong&gt; method. You can set up a &lt;a href="https://masteringbackend.com/posts/laravel-cron-the-definitive-guide" rel="noopener noreferrer"&gt;CronJob&lt;/a&gt; to update the database server every five minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;writeAround&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This strategy allows all the &lt;strong&gt;write&lt;/strong&gt; operations to go directly to the database server without updating the cache server — only during the &lt;strong&gt;read&lt;/strong&gt; operations is the cache server updated.&lt;/p&gt;

&lt;p&gt;Assuming a user wants to create a new &lt;strong&gt;Article&lt;/strong&gt;, the &lt;strong&gt;Article&lt;/strong&gt; stores directly to the database server. When the user wants to read the &lt;strong&gt;Article&lt;/strong&gt;‘s content for the first time, the &lt;strong&gt;Article&lt;/strong&gt; is retrieved from the database server and updates the cache server for subsequent requests.&lt;/p&gt;

&lt;p&gt;You can implement this strategy with the Laravel cache with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;writeAround&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$storedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$storedData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;readOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nv"&gt;$cacheData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$cacheData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Cache Aside (Lazy Loading)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The database is sitting aside in this strategy, and the application requests data from the cache server first. Then, if there’s a hit (found), the data is returned to the client. Otherwise, if there’s a miss (not found), the database server requests the data and updates the cache server for subsequent requests.&lt;/p&gt;

&lt;p&gt;You can implement this strategy with the Laravel cache with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;lazyLoadingStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Database Server is called outside the Cache Server.&lt;/span&gt;
      &lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$callback&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above shows the implementation of the cache Aside Strategy, which is equivalent to implementing the &lt;strong&gt;Cache::remember&lt;/strong&gt; method.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Read Through&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This strategy is the direct opposite of the cache Aside Strategy. In this strategy, the cache Server sits between the Client Request and the Database Server.&lt;/p&gt;

&lt;p&gt;Requests go directly to the cache server, and the cache server is responsible for retrieving the data from the &lt;a href="https://kinsta.com/blog/install-php/" rel="noopener noreferrer"&gt;database server&lt;/a&gt; if not found in the cache server.&lt;/p&gt;

&lt;p&gt;You can implement this strategy with the Laravel cache with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;readThrough&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;);){&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Database Server is called from the Cache Server.&lt;/span&gt;
    &lt;span class="nv"&gt;$DBdata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$DBdata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$DBdata&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There you have it! We’ve now discussed a few popular caching strategies for your next Laravel application. Remember, you can even use a custom caching strategy that best suits your project requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Caching the UI Part of a Laravel App&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Caching the UI of our Laravel App is a concept known as Full Page cache FPC. The term refers to the process of caching the HTML response from an application.&lt;/p&gt;

&lt;p&gt;It’s excellent for applications where the dynamic HTML data doesn’t change frequently. You can cache the HTML response for a faster overall response and rendering of the HTML.&lt;/p&gt;

&lt;p&gt;We can implement FPC with the following line of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ArticlesController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles_index'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles_index'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$news&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;News&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nv"&gt;$cachedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles.index'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$news&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles_index'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$cachedData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                                         
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$cachedData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           
        &lt;span class="p"&gt;}&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, you might have noticed that we check if that &lt;strong&gt;articles_index&lt;/strong&gt; page already exists in our cache server. Then we return the page by rendering it with Laravel’s &lt;strong&gt;view()&lt;/strong&gt; and &lt;strong&gt;render()&lt;/strong&gt; methods.&lt;/p&gt;

&lt;p&gt;Otherwise, we render the page and store the output in our cache server for subsequent requests before returning the rendered page to the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Build a Laravel App&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now we’re going to apply what we’ve learned so far by creating a new Laravel project and implementing Laravel cache.&lt;/p&gt;

&lt;p&gt;If you haven’t used Laravel, you can read through &lt;a href="https://kinsta.com/knowledgebase/what-is-laravel/" rel="noopener noreferrer"&gt;what Laravel is&lt;/a&gt; and peek at our list of &lt;a href="https://kinsta.com/blog/laravel-tutorial/" rel="noopener noreferrer"&gt;excellent Laravel tutorials&lt;/a&gt; to get started.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Setting Up Laravel&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;First, we’re going to create a fresh Laravel instance using the below command. You can look up the official documentation for more.&lt;/p&gt;

&lt;p&gt;Open your console and navigate to where you store your PHP projects before running the commands below. Make sure to have &lt;a href="https://getcomposer.org/" rel="noopener noreferrer"&gt;Composer&lt;/a&gt; installed and configured correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer create-project laravel/laravel fast-blog-app

// Change directory to current Laravel installation
&lt;span class="nb"&gt;cd &lt;/span&gt;fast-blog-app

// Start Laravel development server.
php artisan serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Configuring and Seeding the Database&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Next, we will set up our database, create a new &lt;strong&gt;Article&lt;/strong&gt; model, and seed 500 fake data points for testing.&lt;/p&gt;

&lt;p&gt;Open your &lt;a href="https://kinsta.com/blog/adminer/" rel="noopener noreferrer"&gt;database client&lt;/a&gt; and create a new database. We’ll do the same with the name &lt;strong&gt;fast_blog_app_db&lt;/strong&gt; and then fill up our &lt;strong&gt;.env&lt;/strong&gt; file with the database credentials:&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="nv"&gt;DB_CONNECTION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysql
&lt;span class="nv"&gt;DB_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;127.0.0.1
&lt;span class="nv"&gt;DB_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3306
&lt;span class="nv"&gt;DB_DATABASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;fast_blog_app_db
&lt;span class="nv"&gt;DB_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;//DB USERNAME HERE
&lt;span class="nv"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;//DB PASSWORD HERE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we’ll run the following command to create the migration and the &lt;strong&gt;Article&lt;/strong&gt; model simultaneously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:model Article &lt;span class="nt"&gt;-m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the newly created migration found &lt;code&gt;database/migrations/xxx-create-articles-xxx.php&lt;/code&gt; and paste in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamps&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Reverse the migrations.
     *
     * @return void
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;dropIfExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, run the command below to create a new seeder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:seeder ArticleSeeder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the newly created seeder file found in &lt;code&gt;database/seeders/ArticleSeeder.php&lt;/code&gt; and paste in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the &lt;strong&gt;DatabaseSeeder.php&lt;/strong&gt; file in the same directory and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ArticleSeeder&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, run the command below to create a new factory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:factory ArticleFactory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the newly built factory file found in &lt;code&gt;database/factories/ArticleFactory.php&lt;/code&gt; and paste in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;faker&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="s1"&gt;'description'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;faker&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paragraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, run the command below to migrate our newly created schema and also seed our fake data for testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan migrate &lt;span class="nt"&gt;--seed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Creating the Article Controller&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Next, we will create our controller and set up our routes to handle our request and retrieve data using the above model.&lt;/p&gt;

&lt;p&gt;Run the following command to create a new &lt;strong&gt;ArticlesController&lt;/strong&gt; inside the &lt;code&gt;app/Http/Controllers&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:controller ArticlesController &lt;span class="nt"&gt;--resource&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the file and add the following code to the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Returns all 500 articles with Caching&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Returns all 500 without Caching &lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;allWithoutCache&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, open the &lt;strong&gt;api.php&lt;/strong&gt; file found inside the &lt;code&gt;routes/&lt;/code&gt; folder and paste in the following code to create an endpoint we can call to retrieve our data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/articles'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ArticlesController@index'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/articles/withoutcache'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ArticlesController@allWithoutcache'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Testing the Performance&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Lastly, we will &lt;a href="https://kinsta.com/blog/application-performance-monitoring/" rel="noopener noreferrer"&gt;test the performance&lt;/a&gt; of our app’s response with or without the implementation of the Laravel cache.&lt;/p&gt;

&lt;p&gt;This screenshot shows the response time of the API with cache implemented:&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%2Fuploads%2Farticles%2F07rnfidhxrrv4bahxxqi.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%2Fuploads%2Farticles%2F07rnfidhxrrv4bahxxqi.png" alt="Laravel API response time with cache"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Laravel API response time with cache.&lt;/p&gt;

&lt;p&gt;The following screenshot shows the response time of the API without cache implemented — note that the response time has increased over the cached instance by over &lt;strong&gt;5,000%&lt;/strong&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%2Fuploads%2Farticles%2Fuzdcf33hx0i4zyig9fer.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%2Fuploads%2Farticles%2Fuzdcf33hx0i4zyig9fer.png" alt="Laravel API response time without cache"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Laravel API response time without cache.&lt;/p&gt;




&lt;p&gt;For more Laravel, explore &lt;a href="https://kinsta.com/blog/laravel-tutorial/" rel="noopener noreferrer"&gt;the best laravel tutorials&lt;/a&gt;. Whether you’re a beginner or an advanced Laravel developer, there’s something for everyone in there.&lt;/p&gt;

&lt;p&gt;Got questions about Laravel caching? Just drop a comment below!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>laravel</category>
      <category>tutorial</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Boost Your Laravel App Speed with These Optimization Tips</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Wed, 26 Jul 2023 19:55:12 +0000</pubDate>
      <link>https://dev.to/kinsta/boost-your-laravel-app-speed-with-these-optimization-tips-48b6</link>
      <guid>https://dev.to/kinsta/boost-your-laravel-app-speed-with-these-optimization-tips-48b6</guid>
      <description>&lt;p&gt;Working on a Laravel project? Cool! It's a real powerhouse with its robust security and simple yet sophisticated coding architecture.&lt;/p&gt;

&lt;p&gt;One thing though - Laravel can get slow if you don’t use the right optimization techniques.&lt;/p&gt;

&lt;p&gt;Here are some tips to optimize your Laravel app:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Route Caching&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Route caching is a helpful feature for apps with lots of routes. It saves you time by grouping routes into one command, so your website loads faster. Laravel retrieves the routes from the pre-compiled cache, rather than starting from scratch for each user. To use it, run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan route:cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember to run it every time you make structural changes to your website. To clear the cache, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan route:clear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2. Optimize Composer&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Laravel uses Composer to manage dependencies. When you install Composer, it loads dev dependencies by default, but they slow down your website once it's live. To remove dev dependencies, use the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--prefer-dist&lt;/span&gt; &lt;span class="nt"&gt;--no-dev&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This optimizes the autoloader and boosts performance while keeping necessary dependencies intact. Just be careful not to remove runtime dependencies that your website needs to function properly.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Reduce Autoloaded Services&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The goal of Laravel is to make the development process as breezy for devs as possible. When you launch Laravel, for example, it auto-loads a large volume of service providers listed in the &lt;strong&gt;config/app.php&lt;/strong&gt; file to help you get started with your project quickly.&lt;/p&gt;

&lt;p&gt;While this is a beneficial step by Laravel, you won’t need to use all of these services for building an application.&lt;/p&gt;

&lt;p&gt;Take the REST API for instance. You don’t require services such as View Service Provider or Session Service Provider. In addition, many developers don’t follow the default framework settings. You can simply disable services that are superfluous to your needs (e.g. Pagination Service Provider, Translation Service Provider, Auth Service Provider, etc).&lt;/p&gt;

&lt;p&gt;You’ll be able to improve the speed of your Laravel applications by applying the same principle to other apps. Just make sure you don’t remove any important services, and double-check everything before you drop the hammer.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Use Artisan Commands and Cache Effectively&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Artisan is a popular command-line tool that comes with Laravel. It makes it easy for developers to carry out recurring and complex tasks automatically. Website creators can also use it to conduct tests and generate commands.&lt;/p&gt;

&lt;p&gt;Using Artisan commands cleverly can amp up your app performance. Below, we’ve listed several of the best caching commands you can utilize.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Configuration Caching&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Cache config is an excellent command to get a speed boost. It compiles all of your application’s configuration values into one file so that the framework can load faster. All you need is to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan config:cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that you shouldn’t execute the &lt;strong&gt;config cache&lt;/strong&gt; command during local development. This is because configuration settings may need to be changed often throughout the development of your app.&lt;/p&gt;

&lt;p&gt;To clear the config cache, run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan config:clear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Views Caching&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The view cache is another aspect of the application that contains a cache. The view cache stores generated Blade templates to increase the speed of your project. You can use the artisan command below to compile all views manually and optimize performance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan view:cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember to clear the cache when you upload a new code; otherwise, Laravel will use your old views and you will spend lots of time trying to troubleshoot this. Run this command to clear the view cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan view:clear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Application Caching&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;This is the main cache in Laravel. It saves all the data that you cache manually in your app. Using Laravel’s cache is a smart approach to speed up commonly accessed data and optimize Laravel performance. If you use tags or multiple cache storage, you can flush only certain elements of the cache.&lt;/p&gt;

&lt;p&gt;Here’s the artisan command to clear the Laravel cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan cache:clear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep in mind that this command won’t delete any route, config, or view cache located in the /bootstrap/cache/ folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Reduce Package Usage&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As an &lt;a href="https://kinsta.com/blog/php-frameworks/"&gt;open-source framework&lt;/a&gt; with a populous community, it’s only natural to see more and more packages released or new versions in existing packages in Laravel. You’re free to use them and their features directly in your application.&lt;/p&gt;

&lt;p&gt;You must include these packages in the &lt;code&gt;composer.json&lt;/code&gt; file. Laravel will subsequently install them along with their dependencies.&lt;/p&gt;

&lt;p&gt;Nevertheless, there are a few factors to be considered before adding new packages to any application. They aren’t all designed for the same purpose, for instance. Some packages are also created to perform a broad range of functions.&lt;/p&gt;

&lt;p&gt;When you include packages with lots of dependencies, the application’s size grows, and its performance eventually suffers. That’s why it’s essential to review the dependencies closely before adding any package.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;6. Upgrade to the Latest Version of PHP&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Just like any other bit of code or software program, it’s always best to &lt;a href="https://kinsta.com/blog/php-versions/"&gt;update your PHP version&lt;/a&gt; to the most recent release.&lt;/p&gt;

&lt;p&gt;The primary reason to use an up-to-date PHP version is security. For two years, every PHP release receives security patches and bug fixes. Your system could be jeopardized if you continue to use earlier versions that are no longer being maintained.&lt;/p&gt;

&lt;p&gt;Many developers may also be unaware that the older a PHP version gets, the slower its performance becomes. To boost efficiency, the &lt;a href="https://kinsta.com/blog/php-8-1/"&gt;current PHP release&lt;/a&gt; has outstanding performance improvements such as faster execution of requests, enums, fibers, and inheritance cache.&lt;/p&gt;

&lt;p&gt;Here at Kinsta, we use the latest major PHP version (&lt;a href="https://kinsta.com/feature-updates/php-8-1/"&gt;PHP 8.1&lt;/a&gt;) for all environments so users can benefit from the platform’s extensive capabilities and optimize their apps for maximum speed and efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;7. Use Queues&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Offloading sluggish tasks to a queue job is a simple technique to rapidly maximize the speed of your Laravel application.&lt;/p&gt;

&lt;p&gt;Sometimes you don’t need the information in the UI right away. In this case, such tasks can be postponed and run later in the background by a separate process (e.g. &lt;a href="https://kinsta.com/blog/secure-email-providers/"&gt;sending an email&lt;/a&gt;). This can significantly increase the performance of your app’s online requests.&lt;/p&gt;

&lt;p&gt;Laravel supports a variety of queue drivers such as IronMQ, Redis, Amazon SQS, and Beanstalkd. It additionally includes a built-in queue worker that can be executed using 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;php artisan queue:work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can add a new job into the queue using this method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Queue::push&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SendEmail'&lt;/span&gt;, array&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the method below via Carbon if you want to defer the execution of one of the queued jobs. For example, say you want to schedule a job that sends an email to a client 10 minutes after they create an account:&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="nv"&gt;$date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; Carbon::now&lt;span class="o"&gt;()&lt;/span&gt;-&amp;gt;addMinutes&lt;span class="o"&gt;(&lt;/span&gt;10&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

Queue::later&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$date&lt;/span&gt;, &lt;span class="s1"&gt;'SendEmail@send'&lt;/span&gt;, array&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Overall,&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Laravel is a fast-growing PHP framework, and there are &lt;a href="https://kinsta.com/blog/laravel-tutorial/"&gt;lots of tutorials available&lt;/a&gt; for all kinds of users to learn Laravel regardless of their knowledge level.&lt;/p&gt;

&lt;p&gt;What other methods have you used to speed up your Laravel apps? Let us know in the comments section below.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>webdev</category>
      <category>appconfig</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Build an API for a Marvel Movie Directory Using Node.js</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Mon, 03 Jul 2023 16:01:00 +0000</pubDate>
      <link>https://dev.to/kinsta/build-an-api-for-a-marvel-movie-directory-using-nodejs-4g1g</link>
      <guid>https://dev.to/kinsta/build-an-api-for-a-marvel-movie-directory-using-nodejs-4g1g</guid>
      <description>&lt;p&gt;Want to expand your portfolio and brush up on your dev skills? Follow along with our guide to spinning up an API for an MCU movie directory using Node.js. &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Set up Your Framework
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.fastify.io/"&gt;Fastify&lt;/a&gt; is a great Node.js framework built with performance and developer experience in mind. It's well maintained, has frequent releases, excellent documentation, and the plugin system allows for great extensibility. We would recommend using it for this project. &lt;/p&gt;

&lt;p&gt;After you have installed Node.js and Fastify, ensure your server is working correctly and that it has a route &lt;code&gt;/&lt;/code&gt; that replies back the text “Hello Kinsta”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick tip: if you want to deploy your application don’t forget to use the environment variable “PORT”&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Plus need some more help? Check out &lt;a href="https://www.fastify.io/docs/latest/Guides/Getting-Started/"&gt;this guide&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 2: API Integration
&lt;/h2&gt;

&lt;p&gt;Next, let’s look at &lt;a href="https://www.typescriptlang.org/"&gt;TypeScript&lt;/a&gt; and third-party API integration… &lt;/p&gt;

&lt;p&gt;First, why TypeScript? Its adoption has been growing remarkably and its developer experience is quite enjoyable. The tooling around it has matured into many polished and highly popular tools, libraries, and utilities. &lt;/p&gt;

&lt;p&gt;In this case, the third-party API will be the one that already contains all the MCU movies, and you will have to make a request in your application to retrieve that information.&lt;/p&gt;

&lt;p&gt;You can read its documentation &lt;a href="https://mcu-qdh4b.kinsta.app/docs"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To pass this step we want to be able to search movies by making a request to our application by using the third-party API. For this, you will need to add a route &lt;code&gt;/movies&lt;/code&gt; that would make a request to the &lt;code&gt;https://mcu-qdh4b.kinsta.app/api/v1/movies&lt;/code&gt; endpoint. &lt;/p&gt;

&lt;p&gt;Your route should forward the following parameters of the querystring: filter, page, limit, and order.&lt;/p&gt;

&lt;p&gt;To test your endpoint, making a request &lt;code&gt;/movies?page=1&amp;amp;limit=10&amp;amp;order=chronology%2CDESC&amp;amp;filter=title%3DIron&lt;/code&gt; should return a list of all three Iron Man movies. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Need some more help? Check out these resources if you get stuck:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/"&gt;https://www.typescriptlang.org/docs/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.fastify.io/docs/latest/Reference/Routes/"&gt;https://www.fastify.io/docs/latest/Reference/Routes/&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Quick tip:&lt;/strong&gt; Use types to your advantage to type the function parameters on your endpoints:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d0eF6xlU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2iydz4xp9r0yfjbv4swc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d0eF6xlU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2iydz4xp9r0yfjbv4swc.png" alt="Screenshot of code" width="800" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: PostgreSQL
&lt;/h2&gt;

&lt;p&gt;PostgreSQL is an Open Source database that is battle-tested and used by almost every company out there. ORMs are pretty helpful in abstracting away some of the hassle of generating database queries, and in this case, Prisma has excellent docs and a great TypeScript integration. &lt;br&gt;
First, install PostgreSQL and verify that it’s working correctly.&lt;/p&gt;

&lt;p&gt;Then you will need to add Prisma to your application, which involves creating a &lt;code&gt;schema.prisma&lt;/code&gt; file that defines PostgreSQL as datasource and describes two models: User and Movie. &lt;/p&gt;

&lt;p&gt;The model Movie should have a list of users as one of its fields. Once you’re done with your schemas, don’t forget to generate its types so that you can use them in your app.&lt;/p&gt;

&lt;p&gt;Continue with adding a Fastify plugin that would connect to the database so that once your routes get a request the connection is already established. Use Fastify’s decorators to make the Prisma client available to all of your routes. &lt;/p&gt;

&lt;p&gt;Finally, add a route &lt;code&gt;/movies/add&lt;/code&gt; that would receive a &lt;code&gt;userId&lt;/code&gt; and a &lt;code&gt;movieId&lt;/code&gt; in its request body and that uses Prisma to create a Movie record in the database associated with that &lt;code&gt;userId&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Need some more help? Here are some useful docs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.postgresql.org/download/"&gt;https://www.postgresql.org/download/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.fastify.io/docs/latest/Reference/Plugins/"&gt;https://www.fastify.io/docs/latest/Reference/Plugins/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.fastify.io/docs/latest/Reference/Decorators/"&gt;https://www.fastify.io/docs/latest/Reference/Decorators/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.prisma.io/docs/concepts/components/prisma-client/crud#update"&gt;https://www.prisma.io/docs/concepts/components/prisma-client/crud#update&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#update-or-create-a-related-record"&gt;https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#update-or-create-a-related-record&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re still stuck, check out this example of  “schema.prisma” file:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K5FfHwKA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q3k7dnq6jsmus552alm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K5FfHwKA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q3k7dnq6jsmus552alm6.png" alt="schema prisma file" width="800" height="614"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Testing
&lt;/h2&gt;

&lt;p&gt;Unit testing is used throughout the industry to reduce the number of bugs that are introduced while coding. &lt;br&gt;
There are many testing methodologies (TDD, BDD, etc), but the consensus is that on every large application having unit tests is better than not having any tests at all. &lt;br&gt;
Mocks are useful when the code you need to test has external dependencies (like databases). In this case, you will need to mock Prisma so that your tests don’t rely on a database to be able to run.&lt;/p&gt;

&lt;p&gt;To complete this step, use Jest to add tests for your &lt;code&gt;/movies&lt;/code&gt; and &lt;code&gt;/movies/add&lt;/code&gt; routes. Hint: your Fastify plugin that connects to the database and makes Prisma available as decorator should return a JavaScript function in order to be mocked properly. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Check out these links for more info:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.fastify.io/docs/latest/Guides/Testing/#benefits-of-using-fastifyinject"&gt;https://www.fastify.io/docs/latest/Guides/Testing/#benefits-of-using-fastifyinject&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/jest-mock-extended"&gt;https://www.npmjs.com/package/jest-mock-extended&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 5: Schema Validation
&lt;/h2&gt;

&lt;p&gt;To help prevent malicious actors from triggering unvalidated logic or error messages that are hard to understand, it is important to have schema validation into your app. &lt;br&gt;
 There are multiple ways to integrate it: JSON schema, typebox, Joi, Zod, and others. In this step, we will use typebox for its convenience of translating JSON Schemas into types that we can use in TypeScript. &lt;/p&gt;

&lt;p&gt;Use typebox to define entities (like Movie and User) and parameters (querystring or request body) that will be used in your &lt;code&gt;/movies&lt;/code&gt; and &lt;code&gt;/movies/add&lt;/code&gt; routes. &lt;/p&gt;

&lt;p&gt;Lastly, if you want to improve response times and reduce load on services that your application uses then caching is key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Finally, add a simple in-memory cache for your &lt;code&gt;/movies&lt;/code&gt; endpoint. Whenever a request is done, check if the cache has the results and if it's not cached then store it. Avoid using any external library for doing this. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus points:&lt;/strong&gt; It would be great to limit the number of movies you can cache to avoid running out of memory. While there are many cache eviction strategies, using something like a least recently used strategy should be a nice improvement. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Check out these links for more info:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.fastify.io/docs/latest/Reference/TypeScript/#typebox"&gt;https://www.fastify.io/docs/latest/Reference/TypeScript/#typebox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/@sinclair/typebox"&gt;https://www.npmjs.com/package/@sinclair/typebox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Cache_replacement_policies"&gt;https://en.wikipedia.org/wiki/Cache_replacement_policies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that’s it! You should now have a fully functional API for an MCU movie directory! Share your GitHub link below, and be sure to check out &lt;a href="https://kinsta.com/application-hosting/pricing/hobby-tier/"&gt;Kinsta's Hobby Tier&lt;/a&gt; for easy application hosting for only $7/month.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Keep It Secret, Keep It Safe: How To Use GitHub Actions Secrets To Hide Sensitive Data</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Mon, 26 Jun 2023 05:00:00 +0000</pubDate>
      <link>https://dev.to/kinsta/keep-it-secret-keep-it-safe-how-to-use-github-actions-secrets-to-hide-sensitive-data-26o5</link>
      <guid>https://dev.to/kinsta/keep-it-secret-keep-it-safe-how-to-use-github-actions-secrets-to-hide-sensitive-data-26o5</guid>
      <description>&lt;p&gt;GitHub Actions is GitHub’s built-in continuous integration and continuous delivery (&lt;a href="https://kinsta.com/blog/devops-tools/#devops-pipeline-cicd-tools" rel="noopener noreferrer"&gt;CI/CD&lt;/a&gt;) platform that enables development teams to automate their workflow, including the build, test, and deployment pipeline.&lt;/p&gt;

&lt;p&gt;One disadvantage of using &lt;a href="https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; is that your logs are public, and anyone can access them with the necessary permissions.&lt;/p&gt;

&lt;p&gt;To prevent sensitive data from being exposed in GitHub Actions logs, you should use encrypted environment variables to store sensitive data safely. These encrypted environmental variables are known as GitHub Actions Secrets.&lt;/p&gt;

&lt;p&gt;This post will show you how to use GitHub Actions Secrets to prevent sensitive information from appearing in your GitHub Actions logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Prerequisites:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To follow this tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Make sure you have a &lt;a href="https://kinsta.com/knowledgebase/what-is-github/" rel="noopener noreferrer"&gt;GitHub account&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have an existing GitHub &lt;a href="https://github.com/kinsta/" rel="noopener noreferrer"&gt;repository&lt;/a&gt;. For this tutorial, you can clone this demo repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow these instructions to &lt;a href="https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository" rel="noopener noreferrer"&gt;clone the demo repository&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Keep Your GitHub Action Logs Secure&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When you build workflows using GitHub Actions, any visitor to your repository can view the logs, so they shouldn’t include sensitive information. However, you can’t just delete your tokens, passwords, and other sensitive information — you need them for testing and for your app to function correctly.&lt;/p&gt;

&lt;p&gt;The solution is to hide them with the &lt;code&gt;::add-mask::&lt;/code&gt; workflow command, which puts an asterisk (*) in place of the sensitive data it’s applied to.&lt;/p&gt;

&lt;p&gt;The following section shows you how to mask a log.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Mask Logs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;First, open the cloned repository in your text editor.&lt;/p&gt;

&lt;p&gt;Create the &lt;strong&gt;.github/workflows/&lt;/strong&gt; directory in the root of your repository to store your workflow files. Then, create a new file named &lt;strong&gt;hide-secrets.yml&lt;/strong&gt; in the &lt;strong&gt;.github/workflows&lt;/strong&gt; directory and add the following code to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Hide Sensitive Information
on: push
jobs:
  print-secret-token:
    runs-on: ubuntu-latest
    steps:
      - name: echo a secret
        run: echo "your secret token is verySecretToken"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit the changes and push them to your GitHub repository. The updated GitHub Actions workflow is active and will be triggered whenever you push a new change.&lt;/p&gt;

&lt;p&gt;Open your repository on GitHub and select the &lt;strong&gt;Actions&lt;/strong&gt; tab to view the logs. Your workflow should appear as follows:&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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fpreview-github-workflow.png%2520align%3D" 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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fpreview-github-workflow.png%2520align%3D" alt="Preview your workflow in GitHub"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Examining the workflow logs, you’ll find the &lt;code&gt;verySecretToken&lt;/code&gt; string printed on the logs. Click on your workflow, and then the task name (&lt;strong&gt;print-secret-token&lt;/strong&gt;) to view the log. It should look like this:&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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fgithub-action-logs.png%2520align%3D" 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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fgithub-action-logs.png%2520align%3D" alt="Examine your GitHub action logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To hide it, use the &lt;code&gt;::add-mask::&lt;/code&gt; command, edit the &lt;strong&gt;hide-secrets.yml&lt;/strong&gt; file, and add a new step to the &lt;code&gt;print-secret-token&lt;/code&gt; job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Hide Sensitive Information
on: push
jobs:
  print-secret-token:
    runs-on: ubuntu-latest
    steps:
      - name: Add Mask
        run: echo "::add-mask::verySecretToken"
      - name: echo a secret  
        run: echo "your secret token is verySecretToken"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should add the &lt;code&gt;Add Mask&lt;/code&gt; step at the top, since masking only applies after &lt;code&gt;::add-mask::&lt;/code&gt; has run. If you put the secret &lt;code&gt;verySecretToken&lt;/code&gt; before the &lt;code&gt;Add Mask&lt;/code&gt; step, it will still appear unmasked. So, to ensure the value is masked, it’s essential to use &lt;code&gt;::add-mask::&lt;/code&gt; as soon as possible.&lt;/p&gt;

&lt;p&gt;Once you commit and publish your modifications to your GitHub repository, the string &lt;code&gt;verySecretToken&lt;/code&gt; will be replaced by asterisks (*) wherever it appears in your logs:&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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fplain-text.png%2520align%3D" 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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fplain-text.png%2520align%3D" alt="Make plain texts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While this fixes the masking problem, it introduces a new one. Your &lt;code&gt;verySecretToken&lt;/code&gt; is still in the workflow file, so anyone with access to the source code can see it.&lt;/p&gt;

&lt;p&gt;Another downside of masking plain text is that masking just part of a word will hide all instances of it. For example, take the following sentence: “Programming is great, but my most productive days are those when I do not write a program.” If you mask the word “program,” it won’t only mask the word at the end of the sentence but also anywhere else it appears, such as in “programming.”&lt;/p&gt;

&lt;p&gt;If you try to mask plain text, you’ll end up with something like this:&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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fmasking-plain-texts-problem.png%2520align%3D" 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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fmasking-plain-texts-problem.png%2520align%3D" alt="Problem with masking plain texts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A better approach to hiding sensitive data in GitHub Actions logs is to use GitHub Actions Secrets, as demonstrated in the following section.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Use GitHub Actions Secrets?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You can use GitHub Actions Secrets to store any private data you want to use in your GitHub actions workflow. Secrets are created as key/value pairs at the repository or organizational level.&lt;/p&gt;

&lt;p&gt;While that repository may only access secrets created at the repository level, secrets created at the organization level are shared by all repositories within an organization.&lt;/p&gt;

&lt;p&gt;Secrets created at the repository level are available for use in actions by anyone who has collaborator role permissions. You can change the value of your secrets at any time. However, secrets cannot be used with workflows from a forked repository.&lt;/p&gt;

&lt;p&gt;The following guidelines apply for naming secrets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Secret names can’t contain spaces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secret names are not case-sensitive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secret names cannot begin with a number.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secret names must not begin with the prefix &lt;code&gt;GITHUB_&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secret names must be unique — secrets with the same name can’t exist at the same level.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use these secrets within the GitHub actions workflow by simply adding &lt;code&gt;secrets&lt;/code&gt; before your secret name as a YML variable, as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;${{ secrets.MY_SECRET_TOKEN }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also mask secrets for more security, as shown in the following section.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Mask Secrets&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;First, create a GitHub secret. In your repository on GitHub, click the &lt;strong&gt;Settings tab&lt;/strong&gt;, select &lt;strong&gt;Secrets&lt;/strong&gt; &amp;amp;gt; &lt;strong&gt;Actions&lt;/strong&gt; from the left sidebar, and then click &lt;strong&gt;New repository secret&lt;/strong&gt; to add a new secret:&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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fcreate-repository-secret.png%2520align%3D" 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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fcreate-repository-secret.png%2520align%3D" alt="Create a new repository secret"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give your secret a name and a secret value, then click &lt;strong&gt;Add secret&lt;/strong&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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fadd-github-secret.png%2520align%3D" 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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fadd-github-secret.png%2520align%3D" alt="Add a new GitHub Secret"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you’ve created your secret and given it the &lt;code&gt;verySecretToken&lt;/code&gt; value, you can use it in your workflow file. Open your &lt;strong&gt;hide-secrets.yml&lt;/strong&gt; file and make the following changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Hide Sensitive Information
on: push
jobs:
  print-secret-token:
    runs-on: ubuntu-latest
    steps:
      - name: Add Mask
        run: echo "::add-mask::${{ secrets.MY_SECRET_TOKEN }}"
      - name: Echo a secret  
        run: echo "your secret token is ${{ secrets.MY_SECRET_TOKEN }}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only difference between this and the previous code is that you replaced the secret token with your newly created GitHub secret “&lt;code&gt;${{&lt;/code&gt; &lt;a href="http://secrets.MY" rel="noopener noreferrer"&gt;&lt;code&gt;secrets.MY&lt;/code&gt;&lt;/a&gt;&lt;code&gt;_SECRET_TOKEN }}&lt;/code&gt;.”&lt;/p&gt;

&lt;p&gt;Once you commit the code and push the changes to your GitHub repository, your secrets are masked:&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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fmasked-github-actions-secret.png%2520align%3D" 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%2Fkinsta.com%2Fwp-content%2Fuploads%2F2023%2F03%2Fmasked-github-actions-secret.png%2520align%3D" alt="Masked GitHub Actions Secrets"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;You mustn’t reveal any sensitive information in your GitHub Action logs. Plain text masking is one way to hide data, but anyone accessing your workflow files can see the information you’re trying to hide.&lt;/p&gt;

&lt;p&gt;As this tutorial demonstrates, GitHub Actions Secret is a much more secure approach to safeguard your sensitive data, and then mask it.&lt;/p&gt;

&lt;p&gt;Read our documentation to learn more about &lt;a href="https://kinsta.com/docs/git/" rel="noopener noreferrer"&gt;using Git at Kinsta&lt;/a&gt;. Try our &lt;a href="https://kinsta.com/application-hosting/" rel="noopener noreferrer"&gt;Application Hosting&lt;/a&gt; for free now.&lt;/p&gt;

</description>
      <category>github</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Create and Test an API in Laravel</title>
      <dc:creator>Kinsta</dc:creator>
      <pubDate>Mon, 19 Jun 2023 17:38:00 +0000</pubDate>
      <link>https://dev.to/kinsta/how-to-create-and-test-an-api-in-laravel-2f37</link>
      <guid>https://dev.to/kinsta/how-to-create-and-test-an-api-in-laravel-2f37</guid>
      <description>&lt;p&gt;Laravel &lt;a href="https://laravel.com/docs/9.x/eloquent"&gt;Eloquent&lt;/a&gt; is an easy way to interact with your database. It is an object-relational mapper (ORM) that simplifies the complexities of databases by providing a model to interact with tables.&lt;/p&gt;

&lt;p&gt;As such, Laravel Eloquent has excellent tools for creating and testing APIs to support your development. Read on to see how easy it is to create and test APIs using Laravel.&lt;/p&gt;

&lt;p&gt;You’ll start by creating a model that you can use to build the &lt;a href="https://kinsta.com/knowledgebase/api-endpoint/"&gt;API&lt;/a&gt; and database table. Then, you’ll see how to add a controller as a business logic layer and a route to complete the API. You’ll then learn how to perform testing APIs using Postman before finally focusing on authentication and error handling.&lt;/p&gt;

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

&lt;p&gt;To get started, here’s what you’ll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://laravel.com/docs/9.x/installation"&gt;Laravel version 8 or 9&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://getcomposer.org/download/"&gt;Composer&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.postman.com/"&gt;Postman&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.apachefriends.org/download.html"&gt;XAMPP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Basic knowledge of APIs and &lt;a href="https://kinsta.com/php/"&gt;PHP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;API Basics&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Start by creating a new Laravel project using &lt;code&gt;composer&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer create-project laravel/laravel laravel-api-create-test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start the server, execute the following command, which runs the application server on port 8000:&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;cd &lt;/span&gt;laravel-api-create-test
php artisan serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the following screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DzIFX0Dv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/laravel-landing-page.png%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DzIFX0Dv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/laravel-landing-page.png%2520align%3D%2522left%2522" alt="The Laravel landing page" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, create a model with a &lt;code&gt;-m&lt;/code&gt; flag for the migration using the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:model Product &lt;span class="nt"&gt;-m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now upgrade the migration file to include the required field. Add title and description fields for the product model and these two table fields inside the &lt;strong&gt;database/migrations/{date_stamp}_create_products_table.php&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;longText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is to make these fields fillable. Inside &lt;strong&gt;app/Models/Product.php&lt;/strong&gt;, make &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; fillable fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$fillable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;How To Create a Controller&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now, create a controller file for the product by executing the following command. This will create the &lt;strong&gt;app/Http/Controllers/Api/ProductController.php&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:controller Api&lt;span class="se"&gt;\\&lt;/span&gt;ProductController &lt;span class="nt"&gt;--model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Product
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, add the logic for creating and retrieving the products. Inside the &lt;code&gt;index&lt;/code&gt; method, add the following code to retrieve all the products:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="s1"&gt;'status'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'products'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$products&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, you must add a &lt;code&gt;StoreProductRequest&lt;/code&gt; class for storing the new products in the database. Add the following class at the top of the same file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;StoreProductRequest&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'status'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Product Created successfully!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'product'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$product&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you’ll create the request, which you can do by executing 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;php artisan make:request StoreProductRequest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to add validations, you can use the &lt;strong&gt;app/Http/Requests/StoreProductRequest.php&lt;/strong&gt; file. For this demonstration, there are no validations.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Create a Route&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The final step before testing the API is adding a route. To do so, add the following code inside the &lt;strong&gt;routes/api.php&lt;/strong&gt; file. Add the &lt;code&gt;use&lt;/code&gt; statement at the beginning of the file and the &lt;code&gt;Route&lt;/code&gt; statement in the body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controllers\Api\ProductController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;apiResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'products'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ProductController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before you start testing the API, ensure that the &lt;strong&gt;products&lt;/strong&gt; table is in your database. If it doesn’t exist, create one using a control panel like XAMPP. Alternatively, you can execute the following command to migrate the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;How To Test an API&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before testing the API, ensure that the &amp;lt;code&amp;gt;authorize&amp;lt;/code&amp;gt; method inside the &lt;strong&gt;app/Http/Requests/StoreProductRequest.php&lt;/strong&gt; is set to return &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;.&lt;/p&gt;

&lt;p&gt;Now, you can create a new product using Postman. Start by hitting a &lt;code&gt;POST&lt;/code&gt; request to this URL: &lt;a href="http://127.0.0.1:8000/api/products/"&gt;http://127.0.0.1:8000/api/products/&lt;/a&gt;. Because it’s a &lt;code&gt;POST&lt;/code&gt; request for creating a new product, you must pass a JSON object with a title and description.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Best Apples of the world"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e-IjQYAr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/create-product-postman.png%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e-IjQYAr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/create-product-postman.png%2520align%3D%2522left%2522" alt="Creating a new product in Postman" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating a new product in Postman&lt;/p&gt;

&lt;p&gt;After clicking the &lt;strong&gt;Send&lt;/strong&gt; button, you should see the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pZZrDNl2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/postman-code.png%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pZZrDNl2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/postman-code.png%2520align%3D%2522left%2522" alt="Postman after clicking Send" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After clicking on Send&lt;/p&gt;

&lt;p&gt;Now, fetch the created products using the &lt;code&gt;GET&lt;/code&gt; request. The &lt;a href="https://kinsta.com/knowledgebase/what-is-a-url/"&gt;URL&lt;/a&gt; is the same. The results will look like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TuxpE-OD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/get-code-products-fetched.png%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TuxpE-OD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/get-code-products-fetched.png%2520align%3D%2522left%2522" alt="The products fetched by the GET request." width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Authenticate an API Using Sanctum&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Authentication is crucial when securing an API. Laravel makes it easy by providing the functionality of the Sanctum token, which you can use as middleware. It secures the API using tokens generated when the user logs in using the correct credentials. Remember that users can’t access the secured API without a token.&lt;/p&gt;

&lt;p&gt;The first step to adding authentication is to add a Sanctum package using the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require laravel/sanctum
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, publish the Sanctum configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan vendor:publish &lt;span class="nt"&gt;--provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Laravel&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="s2"&gt;anctum&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="s2"&gt;anctumServiceProvider"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, add Sanctum’s token as middleware. Inside the &lt;strong&gt;app/Http/Kernel.php&lt;/strong&gt; file, use the following class and replace &lt;code&gt;middlewareGroups&lt;/code&gt; with the following code in the protected middleware groups’ API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$middlewareGroups&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'web'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;\App\Http\Middleware\EncryptCookies&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;\Illuminate\Session\Middleware\StartSession&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// \Illuminate\Session\Middleware\AuthenticateSession::class,&lt;/span&gt;
        &lt;span class="nc"&gt;\Illuminate\View\Middleware\ShareErrorsFromSession&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;\App\Http\Middleware\VerifyCsrfToken&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;\Illuminate\Routing\Middleware\SubstituteBindings&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;

    &lt;span class="s1"&gt;'api'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;EnsureFrontendRequestsAreStateful&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'throttle:api'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;\Illuminate\Routing\Middleware\SubstituteBindings&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is to create a &lt;code&gt;UserController&lt;/code&gt; and add the code to get the token to authenticate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:controller UserController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating the &lt;code&gt;UserController&lt;/code&gt;, navigate to the &lt;strong&gt;app/Http/Controllers/UserController.php&lt;/strong&gt; file and replace the existing code with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Hash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// &lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// print_r($data);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nc"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
                    &lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'These credentials do not match our records.'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

             &lt;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'my-app-token'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;plainTextToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="nv"&gt;$response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s1"&gt;'user'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'token'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$token&lt;/span&gt;
            &lt;span class="p"&gt;];&lt;/span&gt;

             &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before you can test the authentication, create a user employing seeders. The following command creates a &lt;strong&gt;UsersTableSeeder&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:seeder UsersTableSeeder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the &lt;strong&gt;database/seeders/UsersTableSeeder.php&lt;/strong&gt; file, replace the existing code with the following code to seed the user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Database\Seeders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Database\Seeder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Illuminate\Support\Facades\DB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Hash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UsersTableSeeder&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Seeder&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Run the database seeds.
     *
     * @return void
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'John Doe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'john@doe.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the seeder using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan db:seed &lt;span class="nt"&gt;--class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;UsersTableSeeder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last step left in the authentication flow is to use the created middleware to protect the route. Navigate to the &lt;strong&gt;routes/api.php&lt;/strong&gt; file and add the products route inside the middleware.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controllers\UserController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'middleware'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'auth:sanctum'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;apiResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'products'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ProductController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"login"&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="nc"&gt;UserController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'index'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After adding a route to the middleware, you’ll get an internal server error if you try to fetch the products.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TN6tldux--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/internal-server-error.png%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TN6tldux--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/internal-server-error.png%2520align%3D%2522left%2522" alt="An internal server error after adding a route" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But once you log in, get a token, and use it in the header, it will authenticate you and start working. You can send a POST request to &lt;a href="http://127.0.0.1:8000/api/login"&gt;http://127.0.0.1:8000/api/login&lt;/a&gt; with the following body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"john@doe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"password"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JwOCj9wa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/authentication-bearer-token.png%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JwOCj9wa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/authentication-bearer-token.png%2520align%3D%2522left%2522" alt="Successful authentication and the Bearer token" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use the token received as a Bearer token and add it as the Authorization header.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UUn3HI4S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/add-bearer-token.png%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UUn3HI4S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://kinsta.com/wp-content/uploads/2023/03/add-bearer-token.png%2520align%3D%2522left%2522" alt="Adding the Bearer token as the Authorization header" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How To Handle API Errors&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Whenever you send a request to the server, it responds. With the response, it also sends a &lt;a href="https://kinsta.com/blog/http-status-codes/"&gt;status code&lt;/a&gt; according to the nature of the response. For example, a 200 status code indicates that the request has succeeded, and a &lt;a href="https://kinsta.com/blog/error-404-not-found/"&gt;404&lt;/a&gt; suggests that the server can’t find the requested resource.&lt;/p&gt;

&lt;p&gt;However, a status code isn’t enough. A human-readable error message is required. Laravel comes with many ways to handle errors. You can use a try-catch block, the fallback method, or send a custom response. The following code you added to the &lt;code&gt;UserController&lt;/code&gt; demonstrates this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nc"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'These credentials do not match our records.'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Laravel’s Eloquent Model makes it effortless to create, validate, and test APIs. Its object-relational mapping provides a straightforward approach to interacting with the database.&lt;/p&gt;

&lt;p&gt;Furthermore, acting as middleware, Laravel’s Sanctum token can help you to secure your APIs quickly.&lt;/p&gt;

&lt;p&gt;And P.S., if you need further optimization, Kinsta’s &lt;a href="https://kinsta.com/database-hosting/"&gt;Database Hosting&lt;/a&gt; solution simplifies setting up and managing databases for all your web projects.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>laravel</category>
    </item>
  </channel>
</rss>
