I’m able to reproduce this with a minimal test case.
It does happen if I output the {{ .Title }} in a <title> tag or any tag in the <head> or <body> as long as that tag is valid
It doesn’t happen if I output the {{ .Title }} in an RSS feed
For context this is the last technical hurdle to cross before I move my 500+ post blog from Jekyll to Hugo and make it live.
I tested this against 500+ posts and out of all of the characters I’ve used in a page title only ', " and + get transformed into ', " and + respectively. This is observable by looking at the source code of the page at the <title> tag, the browser tab’s title or rendering of the page will output the expected character.
Given I wasn’t able to figure out how to solve this I thought I could hack around this by doing <title>{{ replace "You're" "'" "'" }}</title> but even this still produces "You're.
What is performing this processing in such a way that it cannot be overwritten?
I’ve tried a number of things, such as:
Using | safeHTMLAttr or | safeHTML but both options have no effect.
<title>{{ "You're" | printf "%q" | safeHTML }}</title> almost works, this produces "You're" which wraps the string in quotes but those outer quotes wouldn’t want to be in the final output
For the last one I thought I could workaround that but then I discovered something really tricky to understand:
What is allowing this to work with <foo> but not <title>? Is it because <title> is a valid tag name and <foo> is not and Hugo has this list somewhere to do extra processing?
How can I workaround it or configure something to allow this to work with <title> or any valid tag? The title and <h1> tag are arguably one of the most important tags on your page when it comes to SEO. It’s too much of a risk for me to make this live if it changes those characters to be ASCII codes. Search engines will crawl whatever they see in the source code.
Am I missing something? In between changes I cleared out my published directory just to be sure.
I’m using hugo v0.128.2-de36c1a95d28595d8243fd8b891665b069ed0850 linux/amd64 BuildDate=2024-07-04T08:13:25Z VendorInfo=gohugoio which I downloaded off GitHub.
It doesn’t work fine for me when it comes to the <title> tag. The original post mentions trying that unsuccessfully. It still ends up with the ASCII codes.
You need to pass the tags and inner through safeHTML.
git clone --single-branch -b hugo-forum-topic-50915 https://github.com/jmooring/hugo-testing hugo-forum-topic-50915
cd hugo-forum-topic-50915
hugo server
It is documented. Or rather: If you know that there’s such a thing as safeHTML, you can read about it in the documentation. Which also refers to the Go template documentation, although that doesn’t tell us anything more than the Hugo docs.
This
the html/template package escapes strings in certain contexts.
doesn’t help much, either. It’s not clarifying, but obfuscating things.
OTOH: ' is a valid HTML entity. It should be rendered as '. (I even have to escape the & sign in this text so that the entity is shown and not rendered.) What are your issues with these entities?
It is documented but it doesn’t mention you can’t do <title>{{ "You're" | safeHTML }}</title>. In order to get it to work you have to wrap creating the whole tag in a printf call.
That’s what Jmooring’s repo demonstrated. I’m not sure if you looked at it but you have to do this:
This emits the title tag with things correctly set. But then you’d have to do this for your h1, h2, etc. as well.
They weren’t in my previous site because Jekyll used the rendered ' value. Also if you look at most sites on the internet (including this Discourse forum), they do not output the ASCII code, they render a standard character. It’s a lot easier to know that ' is an apostrophe than having to reverse that to an ASCII code.