{"id":2369,"date":"2022-01-26T13:10:35","date_gmt":"2022-01-26T13:10:35","guid":{"rendered":"https:\/\/lvboard.infostore.in.ua\/?p=2369"},"modified":"2022-01-26T13:10:35","modified_gmt":"2022-01-26T13:10:35","slug":"cloudflare-pages-tutorial-deploying-a-react-app-via-github","status":"publish","type":"post","link":"https:\/\/lvboard.infostore.in.ua\/?p=2369","title":{"rendered":"Cloudflare Pages tutorial: Deploying a React app via GitHub"},"content":{"rendered":"\n<h2>Introduction<\/h2>\n\n\n\n<p>React is an ultra-popular frontend library for building user interfaces. As the output is HTML, CSS, and JavaScript, it can be hosted on <a href=\"https:\/\/blog.logrocket.com\/8-ways-to-deploy-a-react-app-for-free\/\" target=\"_blank\" rel=\"noreferrer noopener\">multiple services<\/a> like Github pages or Netlify, to name a few.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Recently, Cloudflare Pages has become <a href=\"https:\/\/blog.cloudflare.com\/cloudflare-pages-ga\/\" target=\"_blank\" rel=\"noreferrer noopener\">generally available<\/a>, which makes it another great service on which to host your React app. Cloudflare Pages is secure, fast, and highly scalable.<\/p>\n\n\n\n<p>In this step-by-step tutorial, we will host a demo React app setup on Cloudflare Pages. Let\u2019s get going.<\/p>\n\n\n\n<h2>Why Cloudflare Pages?<\/h2>\n\n\n\n<p>Of course, React (or any other static output) can be hosted on at least half a dozen services for free. Why should we go for Cloudflare Pages?<\/p>\n\n\n\n<p>In addition to the regular features like preview deployments and Github integration, Cloudflare Pages has custom domains, redirects, and unlimited bandwidth, all for free. All of these features at zero dollars a month, and we get a fast network, security with free SSL, and amazing scalability.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Cloudflare-pages-homepage.png\" alt=\"Screenshot of Cloudflare Pages homepage\" class=\"wp-image-53608\"\/><\/figure><\/div>\n\n\n\n<h2>Prerequisites<\/h2>\n\n\n\n<p>Before we jump into the code below, here are some prerequisites:<\/p>\n\n\n\n<ol><li>Previous knowledge of JavaScript and React<\/li><li>Previous knowledge of npm and npx<\/li><li>Node.js and npm\/yarn working on your environment of choice<\/li><li>Previous knowledge of Git, and a working Github account<\/li><li>A Cloudflare account, for which you can <a href=\"https:\/\/dash.cloudflare.com\/sign-up\/pages\" target=\"_blank\" rel=\"noreferrer noopener\">sign up<\/a> for free<\/li><\/ol>\n\n\n\n<p>Time to get cracking.<\/p>\n\n\n\n<h2>Set up a React app with Create React App<\/h2>\n\n\n\n<p>As the first step of this guide, we will set up React with <a href=\"https:\/\/create-react-app.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">Create React App<\/a> (CRA). If you don\u2019t have CRA installed you can do so with <code>npm install -g create-react-app<\/code>. To initiate a React app boilerplate with CRA we will execute the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">bash\nnpx create-react-app react-cloudflare-pages<\/pre>\n\n\n\n<p>This will set up the whole React boilerplate for us. As soon as it runs, we will see an output like the one below:<a href=\"https:\/\/blog.logrocket.com\/cloudflare-pages-tutorial-deploy-a-react-app-via-github\/\"><\/a><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Create-React-App-install.png\" alt=\"Screenshot of development environment after installing Create React App\" class=\"wp-image-53610\"\/><\/figure><\/div>\n\n\n\n<p>It will take a couple of minutes to download and set up the React boilerplate and finish up with the output as follows:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Create-React-App-post-install.png\" alt=\"Screenshot of Create React App output after install\" class=\"wp-image-53612\"\/><\/figure><\/div>\n\n\n\n<p>As instructed in the image above, to check if our React app is working we can run:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">bash\ncd react-cloudflare-pages\nyarn start<\/pre>\n\n\n\n<p>It will run the development server, and you can run<code><a href=\"https:\/\/localhost:3000\">https:\/\/localhost:3000<\/a><\/code> in your default browser to show an output like so:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Blank-Create-React-App-Screen.png\" alt=\"Default Create React App screen\" class=\"wp-image-53619\"\/><\/figure><\/div>\n\n\n\n<p>Congrats! Our React boilerplate with CRA is working.<\/p>\n\n\n\n<p>Next up, we will push this basic code to Github and later change it to get a list of users from a mock API, and show some of its fields.<\/p>\n\n\n\n<h2>Push the boilerplate code to Github<\/h2>\n\n\n\n<p>To push our basic React boilerplate, we will create a new Github repository as follows:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Create-New-Repository-Github-screen.png\" alt=\"Screenshot of Github's Create New Repository menu\" class=\"wp-image-53620\"\/><\/figure><\/div>\n\n\n\n<p>It is ok to keep it public and empty. Scroll to the bottom of the page and click the <strong>Create Repository<\/strong> button. We will see a page similar to the below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/New-Repository-Setup-github-page.png\" alt=\"Screenshot of Github page after new repository is created\" class=\"wp-image-53623\"\/><\/figure><\/div>\n\n\n\n<p>Next, copy the SSH URL to the Github repository, which in my case was <code>git@github.com:geshan\/react-cloudflare-pages.git<\/code>, and add it as a remote running the following command in our project root to push the code:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">bash\ngit remote add origin git@github.com:geshan\/react-cloudflare-pages.git\ngit push origin master<\/pre>\n\n\n\n<p>It will look something like the following:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Code-pushing-to-github.png\" alt=\"Screenshot of code being pushed to Github\" class=\"wp-image-53625\"\/><\/figure><\/div>\n\n\n\n<p>Consequently, we will update the code to call the mock API and list some of the user details. If you want, you can create a new Git branch to do the following changes, but I will leave that up to you.<\/p>\n\n\n\n<h2>Update the boilerplate to call a mock API<\/h2>\n\n\n\n<p>Our React boilerplate is up and running, and it has been pushed to GitHub too. Now, we will change the code to call a mock list of 10 users and show some fields in our React app.<\/p>\n\n\n\n<p>To do this we will change the <code>src\/App.js<\/code> to look like this below:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">js\nimport {Component} from 'react';\nimport Users from '.\/components\/users';\n\nclass App extends Component {\n  state = {\n    users: []\n  };\n\n  componentDidMount() {\n    fetch('https:\/\/jsonplaceholder.typicode.com\/users')\n      .then(res =&gt; res.json())\n      .then((data) =&gt; {\n        this.setState({ users: data })\n      })\n      .catch(console.log)\n  }\n\n  render() {\n    return (\n      &lt;Users users={this.state.users} \/&gt;\n    )\n  }\n}\n\nexport default App;<\/pre>\n\n\n\n<p>Note that we have removed the unnecessary CSS file and logo.<\/p>\n\n\n\n<p>Time to dive a bit deeper into what the code is doing. First, we are importing <code>Component<\/code> from React, then importing another component called <code>users<\/code>, which we will write next.<\/p>\n\n\n\n<p>Then in the <code>App<\/code> class that extends the React component, we are introducing a state with the <code>users<\/code> array. When the component mounts, we fetch a list of 10 users from our mock API \u2013 <code><a href=\"http:\/\/jsonplaceholder.typicode.com\/users\">http:\/\/jsonplaceholder.typicode.com\/users<\/a><\/code> \u2013 and set it in the <code>users<\/code> of the <code>state<\/code>. In case of an error, we log it.<\/p>\n\n\n\n<p>For the final step in the main <code>App<\/code> component, we render the <code>Users<\/code> component which we will write up next.<\/p>\n\n\n\n<p>As we use the <code>users<\/code> component above, we will create a new file <code>src\/components\/users.js<\/code> that will contain the following:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">js\nconst Users = ({ users }) =&gt; {\n  return (\n    &lt;div className=\"users\"&gt;\n      &lt;center&gt;&lt;h1&gt;Application Users&lt;\/h1&gt;&lt;\/center&gt;\n      {Array.isArray(users) &amp;&amp; users.map((user) =&gt; (\n        &lt;div className=\"user\" key={user.id}&gt;\n          &lt;div className=\"user-details\"&gt;\n            &lt;h2 className=\"user-name\"&gt;{user.name}&lt;\/h2&gt;\n            &lt;h3 className=\"user-email\"&gt;{user.email}&lt;\/h3&gt;\n            &lt;h4 className=\"user-company\"&gt;Company: {user.company.name}&lt;\/h4&gt;\n            &lt;hr\/&gt;\n          &lt;\/div&gt;\n        &lt;\/div&gt;\n      ))}\n    &lt;\/div&gt;\n  )\n};\n\nexport default Users<\/pre>\n\n\n\n<p>Let\u2019s look at how this file works. It is a very simple component that relies on the users being passed in as an array. We check if it is an array and loop through the users. Then we print out the user\u2019s name, email, and user\u2019s company name.<\/p>\n\n\n\n<p>If we want, we can delete the unnecessary files after this change with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">bash\nrm -rf src\/App.css src\/logo.svg src\/App.test.js<\/pre>\n\n\n\n<p>After that we can run <code>yarn start<\/code> and see the following output:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Application-users-list-screenshot.png\" alt=\"Screenshot of application users with name, email, and company name\" class=\"wp-image-53629\"\/><\/figure><\/div>\n\n\n\n<p>Hurray! The mock API is being called properly and we see the user\u2019s name, email, and company name rendering correctly. After this, we will push our code change to GitHub and wire it up with Cloudflare Pages. If you want to look at what files have changed you can have a look at this <a href=\"https:\/\/github.com\/geshan\/react-cloudflare-pages\/pull\/1\/files\" target=\"_blank\" rel=\"noreferrer noopener\">pull request<\/a>.<\/p>\n\n\n\n<h2>Push the app to Github<\/h2>\n\n\n\n<p>To push our changes to the master branch we will run the following commands on the project root:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">bash\ngit add .\ngit add -u #because we have deleted files\ngit commit -m \"Call the mock users API\"\ngit push origin master # if you are in a different branch push that and open a PR<\/pre>\n\n\n\n<p>After the push, you should see the changes reflected in your Github repository as well. Now it\u2019s time to get a Cloudflare Pages URL for our React app.<\/p>\n\n\n\n<h2>Log in to Cloudflare Pages<\/h2>\n\n\n\n<p>To connect your React app with Cloudflare pages, create a Cloudflare account if you haven\u2019t done so already. Then, log in to Cloudflare and click <strong>Pages<\/strong> on the right:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Cloudflare-homepage.png\" alt=\"Screenshot of Google Cloudflare home page\" class=\"wp-image-53637\"\/><\/figure><\/div>\n\n\n\n<p>We will see a page similar to below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Cloudflare-pages-connect-github-page.png\" alt=\"Screenshot of cloudflare pages connect github tab\" class=\"wp-image-53639\"\/><\/figure><\/div>\n\n\n\n<p>Click on <strong>Connect Github account<\/strong>. We will be redirected to Github where we can configure the accounts and repositories we want CloudFlare to access:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/github-install-cloudflare-pages-tab.png\" alt=\"Screenshot of Github install cloudflare pages tab\" class=\"wp-image-53643\"\/><\/figure><\/div>\n\n\n\n<p>Click on the account into which you pushed the above React app (it will probably be your personal account) and choose the right repository to connect to:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Install-authorize-cloudflare-pages-screen.png\" alt=\"Screenshot of Github install and authorize Cloudflare pages tab\" class=\"wp-image-53647\"\/><\/figure><\/div>\n\n\n\n<p>It is better to give access to the required repository only. After giving access we will be redirected to Cloudflare Pages where were can deploy the React app, select the repository, and click <strong>Begin Setup<\/strong> as below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Cloudflare-pages-github-repository-setup-screen.png\" alt=\"Screenshot of Cloudflare Pages after successful link to Github repository\" class=\"wp-image-53649\"\/><\/figure><\/div>\n\n\n\n<p>Next, we will configure the main branch as master:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Cloudflare-pages-setup-builds-deployments.png\" alt=\"Screenshot of Cloudflare pages set up builds and deployments tab\" class=\"wp-image-53650\"\/><\/figure><\/div>\n\n\n\n<p>Scroll below on that page to configure the build settings as follows:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Cloudflare-pages-build-settings.png\" alt=\"Screenshot of cloudflare pages build settings tab\" class=\"wp-image-53651\"\/><\/figure><\/div>\n\n\n\n<p>I had to update <code>npm build<\/code> with <code>yarn build<\/code> in the build command field because CRA uses yarn in place of npm.<\/p>\n\n\n\n<p>Then click <strong>Save and Deploy<\/strong>. If all goes well, the project will be created and start to deploy as seen below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Cloudflare-pages-Pages-tab.png\" alt=\"Screenshot of Cloudflare Pages with Github repo under Pages section\" class=\"wp-image-53652\"\/><\/figure><\/div>\n\n\n\n<p>After a couple of minutes, the build should be done, and if we click the title of the project <strong>react-cloudflare-pages<\/strong> we will see a page like below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Github-repo-deployed-cloudflare-pages.png\" alt=\"Screenshot of github repo successfully deployed in Cloudflare pages\" class=\"wp-image-53653\"\/><\/figure><\/div>\n\n\n\n<p>If we click the link below <strong>Deployment,<\/strong> which is a <code>pages.dev<\/code> URL, we should be able to see our React app deployed on Cloudflare Pages as follows:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Deployed-application-users.png\" alt=\"Screenshot of application users app deployed via Cloudflare pages\" class=\"wp-image-53654\"\/><\/figure><\/div>\n\n\n\n<p>As seen above, it is an HTTPS Cloudflare Pages URL on <code>pages.dev<\/code>.<\/p>\n\n\n\n<h2>Preview deployment in action<\/h2>\n\n\n\n<p>For us to see how previewing deployment works, I am going to change the <code>Company<\/code> label to <code>Company Name<\/code> on line 10 of <code>src\/components\/users.js<\/code>.<\/p>\n\n\n\n<p>We will push it in a branch called <code>preview-deployment<\/code>, which will give us a preview on Github when we open a pull request. After it is built successfully on Cloudflare Pages, it will give us a unique link to the changes as a comment, which can be seen here:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/06\/Cloudflare-pages-deployed-github-comment.png\" alt=\"Screenshot of Github repo with comment by Cloudflare pages stating successful deployment\" class=\"wp-image-53656\"\/><\/figure><\/div>\n\n\n\n<p>This is a very neat feature to see the changes on a fully functioning URL.<\/p>\n\n\n\n<h2>Next steps<\/h2>\n\n\n\n<p>We can easily configure a custom domain for our React app on Cloudflare Pages, which is free as well. In addition, <a href=\"https:\/\/developers.cloudflare.com\/pages\/platform\/redirects\" target=\"_blank\" rel=\"noreferrer noopener\">redirects<\/a> and <a href=\"https:\/\/developers.cloudflare.com\/pages\/getting-started#access-policies\" target=\"_blank\" rel=\"noreferrer noopener\">access control<\/a> for the preview deployments can also be configured. I will leave it up to you to explore them.<\/p>\n\n\n\n<h2>Conclusion<\/h2>\n\n\n\n<p>As we have seen in this step-by-step tutorial, Cloudflare Pages is easy to set up for your React app or any other frontend framework. There is no need to configure a build process on something like Github actions or another CI system.<\/p>\n\n\n\n<p>Connect your Github repo with Cloudflare Pages, and use the build command once as each pull request automatically gets a preview deployment URL. Exploit the power of Cloudflare Pages for free and make your websites fly.<\/p>\n\n\n\n<h2>Full visibility into production React apps<\/h2>\n\n\n\n<p>Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you\u2019re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, <a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\">try LogRocket<\/a>. <a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\"><\/a><a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\"><\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\">LogRocket<\/a> is like a DVR for web and mobile apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app&#8217;s performance, reporting with metrics like client CPU load, client memory usage, and more.<\/p>\n\n\n\n<p>The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.<\/p>\n\n\n\n<p>Modernize how you debug your React apps \u2014 <a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\">start monitoring for free<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction React is an ultra-popular frontend library for building user interfaces. As the output is HTML, CSS, and JavaScript, it can be hosted on multiple services like Github pages or Netlify, to name a few.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[30],"tags":[196],"_links":{"self":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2369"}],"collection":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2369"}],"version-history":[{"count":1,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2369\/revisions"}],"predecessor-version":[{"id":2370,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2369\/revisions\/2370"}],"wp:attachment":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2369"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2369"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2369"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}