Setting Up This Website Part 2 - Making Things Nice
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.
- 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.
- 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. - The
+ Add
button just above where the default domain is shown is what you want. - 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 forwww.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. - 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). - 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.
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:
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.
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.
|
|
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.
./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.