I am writing a blog, and want to be able to link externally to particular sub heading within this blog. How can I add an ID to content within the post body (RTF) ?
There are a few ways, depending on what you want.
ONE-OFF LINKING
Drop an HTML embed in your rich text content, just before your heading, and place something like
<span id="my-link"></span>
Then your link is to the page, affixed with #my-link
.
BLOG-WIDE HEADING LINK SUPPORT
If you want to be able to link to any heading, you can use a ToC package that auto-creates links from headings. Finsweet’s ToC supports this.
Here’s an example using that solution;
https://www.coachmike.live/blog/what-is-love#what-is-love
IN-TEXT MARKUP
Or, you might use Refokus Rich Text Enhancer, which allows constructions like;
[#my-link]This is my heading link here[#my-link]
and adds your link to the text.
Thanks for the response! I didn’t realise you could put HTML into the rich text as that would be an easy solution - however I just tried it, and it just displays as the string. Do I need to do something so it recognises it as code?
Just to be clear I am talking about a CMS blog entry rich text
Make sure you put in actual HTML if that’s what you want, like <span id="my-link"></span>
Cheers, I wasn’t using the insert code thingy, just putting it in. Thanks for the solution
Hey, I ran into this problem today but then did some scoping & created some JS that (in my opinion) functions better than giving headings ID’s
This approach means you can create rich text as normal, with no need to embed HTML. To keep it simple, the JS searches for headings based on their text content & not their IDs. So you simply search for the heading itself, not the ID
Here is what it looks like in action:
https://website.com/page?h=first-heading
The headings would look normal, the function formats it to lowercase & replaces spaces with hyphens)
<h1>First heading</h1>'
Here is the code:
<script>
// Formats Headings
function slugifyTxt(text) {
return text
.toLowerCase()
.trim()
.replace(/\s+/g, "-")
.replace(/[^\w\-]+/g, "")
.replace(/\-\-+/g, "-");
}
window.addEventListener("DOMContentLoaded", (event) => {
const urlParams = new URLSearchParams(window.location.search);
const queryHeadings = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
if (urlParams.has("h")) {
const headingSlug = urlParams.get("h");
for (let heading of queryHeadings) {
if (slugifyTxt(heading.textContent) === headingSlug) {
heading.scrollIntoView({ behavior: "auto" });
break;
}
}
}
// Optional - Copies to clipboard - 1
queryHeadings.forEach((heading) => {
heading.addEventListener("click", function () {
let curUrl = new URL(window.location.href);
let newUrl = curUrl.origin + curUrl.pathname;
const headingQueryText = slugifyTxt(heading.textContent);
copyTextToClipboard(newUrl + "?h=" + headingQueryText);
});
heading.addEventListener("mousedown", function () {
heading.style.opacity = "0.5";
});
heading.addEventListener("mouseup", function () {
heading.style.opacity = "";
});
});
});
// Optional - Copies to clipboard - 2
function copyTextToClipboard(text) {
navigator.clipboard
.writeText(text)
.then(() => {
console.log("Text successfully copied to clipboard");
})
.catch((err) => {
console.error("Failed to copy text: ", err);
});
}
</script>
Just simply paste this in the body tags of the CMS page you want to use it on
NOTE: Within this code, I also implemented a way to copy the link to each heading, by simply clicking the heading you want to copy. If you want to remove this functionality delete the code that says ‘Optional’
Here is also some quality-of-life CSS for you to modify (remove the hover if you don’t want the copy functionality):
<style>
h1,
h2,
h3,
h4,
h5,
h6 {
scroll-margin-top: 50px;
cursor: pointer;
transition: opacity ease 75ms;
}
h1:hover,
h2:hover,
h3:hover,
h4:hover,
h5:hover,
h6:hover {
opacity: 0.9;
}
</style>
P.S: If you want to exclude a specific heading tag by being affected by this code, for example: <h1>
then remove all instances of <h1>
within the JS & CSS