Adding Netlify CMS to your .NET powered static Website The ideal blog website for .NET developers - Part II Friday, 07 May 20218 min read This is part II of the series about creating your own .NET powered static website. Here you can find part I: Create your own .net powered static website for FREE In this tutorial we are going to use NetlifyCMS. Netlify CMS is a flat-file headless CMS. Flat-file means that content is saved to simple files rather than using a database like SQL or MongoDB. In our case, these are Markdown files. A headless CMS is a Content Management System that is completely detached and unaware of any backend systems used to generate your website. This differs completely from the systems we know from the ASP.NET world. A traditional CMS like Umbraco is completely built on top of ASP.NET MVC and uses a SQL database. The content management and public website are very much intertwined and done by the same hosting platform. Flat-file and headless CMS systems are ideal for managing content of simple websites. These systems are usually very nimble and easy to set up. At the end of this tutorial you will have: A repository running your actual clean static public GitHub Page A second private repository running your .NET site-generator/backend that you build in Part I The Netlify CMS that uses Netlify to update your markdown content on GitHub A GitHub Actions attached to your site generator that will automatically update your website Let’s get started and pick up where we left off in Part I. You can also look into my example repo on my GitHub. Step 1 - Adding the Netlify CMS and GitHub repos We start by adding Netlify CMS so we can add and manage our content in a friendly manner. Open the project you created in Part I and create an admin directory inside the input directory. In this directory we create an index.html file with the following magic Netlify CMS code: ShouldOutput: true --- <!doctype html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Content Manager</title> </head> <body> <!-- Include the script that builds the page and powers Netlify CMS --> <script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script> </body> </html> Now we are going to push our code to a new GitHub repo on your GitHub. We can easily do this in the latest version of VS2019 using ‘Git Changes’. Make sure you give your repository a meaningful name like ‘MyWebSiteGenerator’. Please don’t tell me you don’t have a GitHub account!!! Shame on you, you call yourself a developer 😜 ??? Step 2 - Registering your GitHub Page Now your code is in GitHub we will have to add some magic to hook up the NetlifyCMS. For this we first need to set up a Netlify site (we are not going to use this site… complicated I know. And, ‘Yes I wish there was a better way…’) But first, now we are in GitHub, let’s do some plumbing for our GitHub page. Create a new public repository on your GitHub and name this repository <YourGithubName>.github.io. This will also be the domain where your website is hosted. Next we need to hook up your code to automatically deploy to this GitHub Page. Go inside the newly created Page repo and go to the ‘Settings’ tap and select 'Pages'. Press ‘Choose a theme’ and select the first theme and press ‘Select theme’. This will generate a branch called ‘gh-pages’ where the selected theme will deploy. Don’t worry we are going to overwrite this default theme with our own awesome static website. If you know go to the ‘Pages’ section in your repo ‘Settings’, you should see in green ‘Your site is published at https://<YourGithubName>.github.io/’. If it says published at https://<YourGithubName>.github.io/<RepoName>/’ then you did not name your repo correctly <YourGithubName>.github.io. This will not work because the blog site expects to be published inside the root of your website domain! Step 3 - Setup Netlify CMS To set up Netlify CMS follow the first two steps ‘creating an GitHub OAuth App’ and ‘Creating a Netlify Site’ from the following great blog. Now we can add the config.yml to /input/admin directory inside your code. This is the heart of the Netlify CMS. You can download my config.yml from my GitHub Repo. I’ve gone ahead and configured this config.yml file for you. You only have to change the backend settings inside the config.yml to target the GitHub Repo where your site generator lives (so not your GitHub Pages Repo). So change ‘repo: <GitHubName>/<RepoName>‘ i.e. feiko/StaticBlogExample. Also change the site domain 'site_domain' to the <SiteName>.netlify.app you just created when configuring Netlify. If you use a different branch then ‘master’ please also change this setting. Go ahead and git commit and push this config.yml to GitHub. Now you can preview the site locally using the dotnet run -- preview command (see Part I) and browse to ‘localhost:5080/admin’. You should be able to log into your CMS using your GitHub credentials. Now you can write a blog or page in the CMS. Netlify will automatically commit your new content to your remote GitHub repo. To preview the changes locally, you need to ‘git pull’ the content from your remote repo. Run the preview site and enjoy your freshly written blog… locally… Note: Don’t forget to commit and push your local changes to GitHub. You can also add the /output folder to the .gitignore file so you don’t keep pushing and pulling these changes. Note: If the admin page is displayed malformed mixed with CleanBlog theme elements. Then we need to tell Statiq to ignore the admin directory. If everything looks okay, then ignore this step. To tell Statiq to ignore the /input/admin directory you can insert the following code to program.cs after ‘.CreateWeb(args)’. .AddSetting(WebKeys.ExcludedPaths, new List<NormalizedPath> { new NormalizedPath("input/admin"), }) Step 4 - Deploy your site to GitHub Pages Finally we come to the magic Sauce. We are going to host our site on our GitHub Page and use GitHub Actions to update your website automatically every time you commit a change in your CMS or on your GitHub repo. First we are going to generate a token to allow Github Action to update your GitHub Pages. For this login into GitHub.com. In the top right click on your icon and in the drop-down menu select ‘Settings’. Now select ‘Developer Settings’ and then select ‘Personal access tokens’. Click ‘Generate new token’. Give the token a recognizable name in ‘Note’ i.e. ‘Page Token’, then only check ‘public_repo’ under ‘Select scopes’, at the bottom click the green ‘Generate token’ button. Copy the generated token to a temp document for later use. Now we tell Statiq where to deploy or website, by adding the following code to Program.cs, after ‘.CreateWeb(args) .DeployToGitHubPagesBranch( "<githubName in my case: feiko>", "<RepoName Github Pages, in my case: feiko.github.io >", Environment.GetEnvironmentVariable("GITHUB_TOKEN"), "<the branch name that holds the page content, in my case: gh-pages>" ) My complete program.cs looks like this: using System; using System.Collections.Generic; using System.Threading.Tasks; using Statiq.App; using Statiq.Common; using Statiq.Web; namespace StaticBlogExample { public class Program { public static async Task<int> Main(string[] args) => await Bootstrapper .Factory .CreateWeb(args) .DeployToGitHubPagesBranch( "feiko", "feiko.github.io", Environment.GetEnvironmentVariable("PAGE_TOKEN"), "gh-pages" ) .AddSetting(WebKeys.ExcludedPaths, new List<NormalizedPath> { new NormalizedPath("input/admin"), }) .RunAsync(); } } You can optionally test this code by changing the ‘Environment.GetEnvironmentVariable("PAGE_TOKEN")’, to the token string you copied earlier. Now run dotnet run -- deploy. Your content should now be visible inside your GitHub pages repo and you can visit your static website at ‘https://<YourGithubName>.github.io/’. It can take a couple of minutes for GitHub to start hosting your site the first time. Never commit your GitHub token to GitHub. So be sure to change this line back after you’ve finished. If you have published your token by accident, your token will no longer work and you have to renew your token.* Now make sure you commit and push your code to GitHub for the last time. Step 5 - Automatic deployment using GitHub Actions The last step is to create a GitHub Action that will run the website generator every time you update your website using your CMS or checking in some new code. Go to GitHub and open the Repo with your site generator code (not your GitHub Page repo). Open the tab ‘Actions’ and click ‘set up a workflow yourself ->’. Replace the code inside the editor with the following script: name: Publish GitHub_Page on: push: branches: [ master ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup .NET uses: actions/setup-dotnet@v1 with: dotnet-version: 5.0.x - run: dotnet run -- deploy env: PAGE_TOKEN: ${{ secrets.PAGE_TOKEN }} Then press the green ‘start commit’ button. Finally we need to generate an authorization token that will allow Actions to deploy to GitHub Pages. Go to the ‘settings’ tap of your site-generator-repo and in your left menu select ‘Secrets’ to create a secret for your GitHub commit token. Click ‘New repository secret’. Name this secret ‘PAGE_TOKEN', inside the ‘Value’ paste the token you generated earlier. Now press ‘Add secret’ and voila your token is stored securely inside your GitHub Repo. To kick off the action and deploy your site the first time you need to make a Git commit to your website. The easiest way to do this is by creating a readme.md inside the root of your site generator repo in Github. This commit will kick off the action. You can see your action status in the GitHub ‘action’ tab. After your Action has run successfully, you see your static blog at https://<YourGithubName>.github.io/. From now on all changes you make inside your CMS https://<YourGithubName>.github.io/admin/, will be committed to the GitHub websiteGenerator repo. This will kick off the action and update your website. And now you're done! Congratulations, how cool! You see, now all .NET geeks can blog like Scott Hanselman! I can’t wait for you to share your knowledge with the world. If you want to create a more special website like myself, you can create your own theme or reuse a theme you already have. Be sure to check out the documentation on https://statiq.dev/web/, also look at the documentation of Netlify CMS on how to configure your config.yml file. Happy coding! Conclusion Having a .NET powered static page generator made my life a lot easier. I was able to reuse a lot of my old ASP.NET knowledge when creating my own web theme. Setting up Netlify CMS together with a Netlify account can feel a bit circumstantial. But having a CMS experience makes adding content a lot easier. Because we have used a flat-file headless CMS we can easily switch from the CMS system. Perhaps in the future we would have a CMS built using .NET Blazor, that would be really awesome! Please let me know if you found this blog helpful or have any questions. Happy coding!