Setting Up This Website Part 2 - Making Things Nice

Posted on Dec 16, 2021

If you load up your website with the URL that Microsoft gives you (it’s like best-coast-928u592u5.azurestaticapps.net or whatever) you’ll perhaps find that your website is lacking a little bit of… stuff. If you don’t find that then you have a very spartan theme or you already adjusted some things in your config.toml to get it going. If you’re new to Hugo then this will certainly help out.

Table Of Contents

Master of your domain

You can absolutely have an actual domain on an Azure Static Web App (which has a free tier) and you will absolutely be able to get a free SSL certificate with it. Yeah, I know it’s TLS but SSL sounds great. There’s also more than one SSL (Solid State Logic) and they rock, so to be clear I’m talking about “Transport Layer Security” that used to be officially called “Secure Socket Layer” which stopped being a thing in the 90’s but, at that point, it had already caught on. It had a good name. Secure Socket Layer. That socket was secure. It feels good. It was initially very insecure. Marketing matters. Having a domain name is similar.

SSL, as we call TLS (it’s fine–no one will call you out for using “SSL”; this was mostly for the “well, actually” crowd but also for your personal edification, if you’re into that) is an asymmetric or public key/private key encryption technology that allows for two computers to create a secure connection without either side giving up any secrets. The idea of the public and private keys, generally logically packaged as the certificate, allows a web browser to not only start a secure connection with the web server but also positively identify that the web server is the one that was intended to be contacted.

For this to happen we require some level of technical trust and that comes in the form of cryptographic signing which is, again, using the public and private keys of companies like Digicert and Network Solutions. SSL certificates need to be issued by these large CAs (certificate authority) and, subsequently, they would get paid. A goodly amount. Certs have gone down in price but, depending on how you are set up (or your organization), you may need to pony up for a new web cert every year. Don’t, though. Azure will give you a free SSL cert for your domains on your site. LetsEncrypt will also give you a free cert but there’s a little more legwork there. It’s immaterial to us but you can upload your own certificate, or a corporate certificate, if the need arises.

Browse your record collection

I’m going to add my domain, marktoso.com, as well as www.marktoso.com because it’s just good manners. So this will involve going to your DNS provider (usually your domain name registrar) and adding some records. I’ve compiled a brief list of the more popular registrar’s page on how to do that:

You do have a domain name, already, I assume. And you are familiar with DNS? Domain Name System? It’s what gets the “marktoso.com” that you typed into the address bar and translates it to an IP address that your ISP can then route the request to. It’s a huge hierarchical distributed (sort of) system and it’s cool stuff. It’s extremely important and, like certificates, can be the cause of a lot of headaches. If you don’t have the express need to tightly manage certificates or DNS then don’t. The saying is “even when it isn’t certs, it’s always certs. And when it isn’t certs it’s always DNS.” Many hours of troubleshooting gone to issues in these realms.

The purpose of this part is to let the world know that the domain, in this case “marktoso.com”, is the best-coast-928u592u5.azurestaticapps.net serer that Azure has so wonderfully set up for our application to live in. Why wouldn’t it be an IP address? Because Azure itself is a huge seething mass of interconnected computers and IP address can change. Domain names, however, can be kept consistently and their records can be updated so no one is beholden to keeping your static web app at the IP 10.25.59.12 all day every day. Resources can be reallocated and migrated. This is, ultimately, what cloud is about and we’re catching a glimpse.

Adding a custom domain to your Static Web App

I realize that I glossed over DNS but it’s a larger topic. It is medium important to know that there are distinct types of DNS records and the ones that we will be concerned with in this process are TXT “text” records, ALIAS records, and CNAME “c-name” records. A TXT record is akin to a footnote, if that makes sense? You’ll normally, as a person, never interact with a TXT record but it’s information for a lot of machine purposes. This process of validating your ownership of the domain is a perfect example. CNAME is short for Canonical Name which is used to give another “real” name to a domain. The default domain is “best-coast-928u592u5.azurestaticapps.net” and that one has it’s A record (address record) managed by Microsoft–we are going to manage our CNAME record to point to that other domain name to ensure the IP stays lined up with it. ALIAS records are a lot like CNAME records but, instead of being tied 1:1 it can relate to a few things. ALIAS records are used for root domains.

  1. Head to the Azure Portal and, if your Static Web App isn’t in the “Recent resources” section, type “Static Web Apps” in the bar at the top of the page. Find your static web app and go in there.
  2. On the left side of the web app’s blade (yeah, this is still Xbox 360 vibes a little bit) there’s Custom Domains. Go there.
  3. The + Add button just above where the default domain is shown is what you want.
  4. Here there will be some directions as to how to proceed adding a custom domain. Firstly, type in your domain name. In my case I typed in marktoso.com. After I finished the process of validating the root domain I went back and did it again for www.marktoso.com. With a free-tier app I think you only get two additional domains. That’s fine but, at the moment, I’m at capacity. If I need to change it at any point I can.
  5. To add a root domain you should use the TXT validation method. The page gives you what type of record (TXT) and what host (@ - which means the root domain) and will allow you to generate a code to be the value of the record. This should match up to whatever your DNS provider has on adding records as it’s very standard. Once you generate that code Azure will start trying to check for it. It may take minutes or hours for your DNS provider to update the DNS entries for your domain (it used to take days to update a DNS record).
  6. If you added your root domain but want to add your www subdomain then you can go through the same process but add a CNAME record. You won’t need to revalidate.
    💡 It’s important that you ensure that any domains you have directed to your static web app from your DNS provider have corresponding (and valid) entries in the “Custom domains” portion of your web app because this is how Azure will know what domains to include in the SSL certificate.

You’re pretty much done! From here you can also click on one of the domains and use the ☆ Set default button to have the other domains redirect to that default domain. This is important because there is something that we’re going to edit to make the site work a little better.

The implications of SSL

So what might be apparent, if you haven’t edited your config.toml in Hugo, is that your resources, like CSS, are really messed up. Here’s a picture of this site as it sits online right now.

There are no external CSS files loaded on the page at all.

Why is this happening? It looks great when I preview it on my machine using the hugo server command. It’s that nifty SSL again. The devil is in the details and there is an interesting detail that is being overlooked here. But to find that out let’s open the developer tools in our browser. Firefox, Chrome, Edge, and Safari all have their own fun ways of getting into the developer tools but, on the Chromium browsers, I usually go for ⌘ + ⇧ + C (if you’re rocking the , or Ctrl + Shift + C on a Windows keyboard [unless it’s a Windows keyboard on a mac–then it’s Alt + Shift + C if memory serves]). Navigate to the Network tab (it varies per browser) and make sure it’s keeping track of your network requests. Hit refresh and you’ll get a breakdown of all the requests and responses from the web server. With a theme as basic as this it’s very few but more complicated sites can make hundreds of requests to load a page. You’ll see some red on it:

The resource files are all being block as “mixed content”.

Mixed content? I already changed the baseURL value in config.toml to http://www.marktoso.com and it hasn’t complained yet. Well, the site has a valid SSL cert and a cool lock up there in the address bar. It’s very secure. But here’s the implication of security–you need to do everything right. This is a static site with no real “interactivity” to speak of so it’s clear to see what the “everything” is and we are very obviously doing something wrong. If we view the source code for the page and look for any of these files we might end up seeing something that ties them together–because the site works otherwise.

The resource files are all being block as “mixed content”.

There it is. I messed up the baseURL value. Hugo uses that for the resource files and they aren’t loading because they are “http” and not “https” (the s is for Secure). At the level of risk that we, as people, are at every day browsing the web it has been decided that showing mixed content (i.e. a secure page loading insecure resources) is not going to be allowed. It makes sense. Resolving it shouldn’t pose a problem. Going into the config.toml and changing that to https should make everyone happy.

Spice up the Hugo theme

Maybe “spicing it up” is a bit more suggestive than what I’m actually going to do but I am going to point out the proper way to override a Hugo template to just give it a slightly different spin. I dig a little easter egg on the page somewhere unimportant. That somewhere is the footer. There’s a little space there that could use something. I’m also going to add some functionality that is part of Hugo but wasn’t implemented in this theme. In the event that it’s changed–as of the time of this writing I’m using the Archie theme. And that’s an old Internet thing.

What’s a motto with you?

Mottos need to be in Latin, right? They can be somewhat silly. Maybe a little frivolous. It’s all fun and games. If you look down at the footer anymore and you don’t see it, then I’ve changed my mind since I wrote this. I had a discussion some time ago with a friend and we were talking about mottos and got around to something like “speak out loud” but, well, it needs to be in Latin. I, for the express purposes of this post, have refined it to “speak loudly” however it gets a bit dicey when you translate it to Latin. I went to the interim language of Spanish and figured “hablaré en voz alta” which ends up being more like “I will, in the future, speak loudly”. It went into “ego dicam ex magna” but I finally settled on “dicam ex magna”. Speaking with the big voice. Like in Dune, I guess.

This change will require an override to a file that is defined in the theme but Hugo is good and has a concept for this in the fact that there is a /layouts folder that is empty by default. That folder will take priority over anything in the /themes/<yourtheme>/layouts. So we do some digging in this theme’s layouts folder and find that there is a folder /themes/layouts/partials. Partials are a cool concept in that they’re the reused “parts” of a page. I’m not going to get into creating partials at the moment but I will definitely go into editing one. It’s got a file called footer.html and that sounds like it is precisely what we’re looking for.

You’ll need to duplicate the structure of the theme’s layouts folder to ensure that Hugo knows exactly which file it’s going to override.

# starting from the root of the Hugo project 
mkdir layouts/partials
cp themes/layouts/partials/footer.html layouts/partials/footer.html

Here’s what that file looks like in the Archie theme.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<footer>
<hr>
{{- range $index, $key := .Site.Params.Social -}}
<a class="soc" href="{{ $key.url }}" title="{{ $key.name }}"><i data-feather="{{ $key.icon }}"></i></a>|
{{- end -}} 
	{{ dateFormat "2006" now }} {{ with .Site.Copyright }} {{ . }} | {{ end }} <a href="https://github.com/athul/archie">Archie Theme</a> | Built with <a href="https://gohugo.io">Hugo</a> 
</footer>
{{ if not .Site.IsServer }}
{{ template "_internal/google_analytics_async.html" . }}
{{ end }}

{{- if (isset .Site.Params "social") -}}
<script>
      feather.replace()
</script>
{{- end -}}

Line 6 (not a modeling amplifier) is where it’s going to happen. Sorry for it being so long but you’ll need to scroll. So there’s a couple of cool things happening here. dateFormat just get’s the date from the time of the build and drops it in there. Really great stuff. It starts to get fun with the with. with takes a parameter that is a parameter somewhere in the site. In this particular case the .Site scope really means config.toml at the top level. We can open up that file and drop our motto in there to make it easier and cleaner to transport across themes if need be.

[params]
	mode="auto" # color-mode → light,dark,toggle or auto
	useCDN=true # don't use CDNs for fonts and icons, instead serve them locally.
	subtitle = "They say that tech always Marks the spot. Take a look at IT through the lens of a 12-year veteran in higher ed who is looking to improve and grow. Puns aren't only welcome--they're encouraged."
	motto = "dicam ex magna"

It’s important to note that it is in the [params] section. I’ve added the following to the end of line 6 and I will break it down.

{{ with .Site.Params.motto }} | {{ . }} {{ end }}

So what’s happening here is that with takes .Site.Params.motto and puts it in the immediate context. When you drop {{ . }} it will spew out that immediate context, which is the variable motto’s value as assigned in config.toml and renders it to the HTML. You’ll also note that I put the | in there as well. I don’t want a | hanging out in the event that I don’t want the motto there anymore and I just comment it out of the config file. with will take the action between it and {{ end }} only if that parameter evaluates as being something. If it’s empty or doesn’t exist then the with code block just doesn’t execute. Hugo generates static page but it does so dynamically.

Contents with context

This theme didn’t implement a table of contents. I, personally, enjoy them. They help you get where you’re going quicker. Hugo has the functionality to render a table of contents (sick, right?) It’s actually pretty straightforward in that you just drop {{ .Page.TableOfContents }} into a page but .Page is something that can only be accessed in the template so when we need to blend templates and content we turn to shortcodes. They’re like partials but they aren’t placed in a layout–they go right in to the markdown. It’s very cool.

Make the folder /layouts/shortcodes and create a file called toc.html.

<div>
    <h2>Table Of Contents</h2>
    {{ .Page.TableOfContents }}
</div>

That’s all it takes to generate the table of contents that you’re seeing above. Well, that’s the building of it. But to call it you just put {{< toc >}} right in your content and it will show up. I would call shortcodes the “functions” of Hugo. Even though there are actual functions. These are perhaps user-defined layout-capable functions. They can take parameters and can end up building things more dynamically than one would think.

That was a beefy post and a crash course in Azure custom domains, DNS, Hugo layouts, and shortcodes. If you have any questions or comments please reach out.

Hi, this post was checked with vale which is a content-aware linter. It was checked using the Microsoft style as well as some rules that I made. A summary of those results is below. More details as to how this was put together check out this post. This post had: 20 errors, 84 warnings and 0 suggestions For details on the linting of this post
 ./content/posts/setting-up-this-website-part-2.md
 10:38    warning  For a general audience, use     Microsoft.GeneralURL         
                   'address' rather than 'URL'.                                 
 10:196   warning  In general, don't use an        Microsoft.Ellipses           
                   ellipsis.                                                    
 10:247   warning  Consider removing 'very'.       Microsoft.Adverbs            
 15:169   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 15:325   warning  Use first person (such as       Microsoft.FirstPerson        
                   'I'm') sparingly.                                            
 15:611   warning  Consider removing 'very'.       Microsoft.Adverbs            
 17:9     warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 17:392   warning  Consider removing 'generally'.  Microsoft.Adverbs            
 17:531   warning  Consider removing               Microsoft.Adverbs            
                   'positively'.                                                
 19:20    warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 19:708   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'us'.                               
 22:1     warning  Use first person (such as       Microsoft.FirstPerson        
                   'I'm') sparingly.                                            
 22:18    warning  Use first person (such as       Microsoft.FirstPerson        
                   'my') sparingly.                                             
 28:36    warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 28:328   warning  Consider removing 'extremely'.  Microsoft.Adverbs            
 28:452   warning  Consider removing 'tightly'.    Microsoft.Adverbs            
 30:81    error    Punctuation should be inside    Microsoft.Quotes             
                   the quotes.                                                  
 30:169   warning  Consider removing               Microsoft.Adverbs            
                   'wonderfully'.                                               
 30:192   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like                                     
                   'our'.                                                       
 30:581   warning  Consider removing               Microsoft.Adverbs            
                   'ultimately'.                                                
 30:617   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 33:1     warning  Use first person (such as 'I    Microsoft.FirstPerson        
                   ') sparingly.                                                
 33:15    warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 33:60    error    Use 'it's' instead of 'It is'.  Microsoft.Contractions       
 33:156   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 33:745   error    Use 'we're' instead of 'we      Microsoft.Contractions       
                   are'.                                                        
 33:745   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 33:768   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like                                     
                   'our'.                                                       
 37:122   warning  Use first person (such as       Microsoft.FirstPerson        
                   'my') sparingly.                                             
 37:129   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 37:162   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 37:215   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 37:289   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 37:367   warning  Use first person (such as       Microsoft.FirstPerson        
                   'I'm') sparingly.                                            
 37:386   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 37:419   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 38:312   warning  Consider removing 'very'.       Microsoft.Adverbs            
 42:221   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 44:24    warning  Avoid using acronyms in a       Microsoft.HeadingAcronyms    
                   title or heading.                                            
 45:26    error    More than 3 commas!             marktoso.TresComas           
 45:114   warning  Consider removing 'really'.     Microsoft.Adverbs            
 49:43    warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 49:60    warning  Use first person (such as       Microsoft.FirstPerson        
                   'my') sparingly.                                             
 49:194   error    Use 'that's' instead of 'that   Microsoft.Contractions       
                   is'.                                                         
 49:246   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like                                     
                   'let's'.                                                     
 49:280   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like                                     
                   'our'.                                                       
 49:400   error    More than 3 commas!             marktoso.TresComas           
 49:771   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 49:1195  warning  Consider removing 'very'.       Microsoft.Adverbs            
 51:45    error    Punctuation should be inside    Microsoft.Quotes             
                   the quotes.                                                  
 53:15    warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 53:212   warning  Consider removing 'very'.       Microsoft.Adverbs            
 53:413   error    Use 'we're' instead of 'we      Microsoft.Contractions       
                   are'.                                                        
 53:413   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 53:420   warning  Consider removing 'very'.       Microsoft.Adverbs            
 53:461   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 53:530   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 57:7     error    Use 'it's' instead of 'it is'.  Microsoft.Contractions       
 57:13    warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 57:117   error    Use 'they're' instead of 'they  Microsoft.Contractions       
                   are'.                                                        
 57:202   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 57:299   error    Use 'that is' instead of        Microsoft.Foreign            
                   'i.e.'.                                                      
 57:346   error    Use 'isn't' instead of 'is      Microsoft.Contractions       
                   not'.                                                        
 60:58    warning  Use first person (such as       Microsoft.FirstPerson        
                   'I'm') sparingly.                                            
 60:86    warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 60:196   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 60:343   warning  Use first person (such as       Microsoft.FirstPerson        
                   'I'm') sparingly.                                            
 60:384   error    Use 'that's' instead of 'that   Microsoft.Contractions       
                   is'.                                                         
 60:443   warning  Consider using 'if' instead of  Microsoft.Wordiness          
                   'In the event that'.                                         
 60:506   warning  Use first person (such as       Microsoft.FirstPerson        
                   'I'm') sparingly.                                            
 62:27    warning  Don't use end punctuation in    Microsoft.HeadingPunctuation 
                   headings.                                                    
 63:193   warning  Use first person (such as       Microsoft.FirstPerson        
                   'my') sparingly.                                             
 63:206   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 63:272   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 63:386   warning  Use first person (such as ' I,  Microsoft.FirstPerson        
                   ') sparingly.                                                
 63:455   warning  Consider removing 'loudly'.     Microsoft.Adverbs            
 63:629   error    Punctuation should be inside    Microsoft.Quotes             
                   the quotes.                                                  
 63:659   warning  Consider removing 'loudly'.     Microsoft.Adverbs            
 63:705   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 63:727   error    Punctuation should be inside    Microsoft.Quotes             
                   the quotes.                                                  
 63:787   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 65:48    error    Use 'that's' instead of 'that   Microsoft.Contractions       
                   is'.                                                         
 65:167   error    Use 'that's' instead of 'that   Microsoft.Contractions       
                   is'.                                                         
 65:279   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 65:463   warning  Use first person (such as       Microsoft.FirstPerson        
                   'I'm') sparingly.                                            
 65:526   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 65:624   error    Use 'it's' instead of 'it is'.  Microsoft.Contractions       
 65:647   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 92:1     error    Use 'that's' instead of 'that   Microsoft.Contractions       
                   is'.                                                         
 92:254   warning  Consider removing 'Really'.     Microsoft.Adverbs            
 92:424   warning  Consider removing 'really'.     Microsoft.Adverbs            
 92:469   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'We'.                               
 92:503   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like                                     
                   'our'.                                                       
 102:29   error    Use 'it's' instead of 'it is'.  Microsoft.Contractions       
 102:111  warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 106:287  warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 106:351  warning  Consider using 'if' instead of  Microsoft.Wordiness          
                   'in the event that'.                                         
 106:368  warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 106:409  warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 109:49   warning  Use first person (such as ' I,  Microsoft.FirstPerson        
                   ') sparingly.                                                
 109:371  warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 109:410  warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 109:530  warning  Consider removing 'very'.       Microsoft.Adverbs            
 118:202  warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 122:210  warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                

20 errors, 85 warnings and 0 suggestions in 1 file.