The FooterRef after the body of the article is starting to shape up! This
time it wasn’t too hard, since I figured out where the frontmatter lives
after creating the next/prev button component. Here’s an example of a footnote
reference list converted from frontmatter to HTML,
As for frontmatter.source, I had some fun with simple animations,
It grew from something simple to that big zoom-in, played around with the scale
and width. Don’t know how long I’ll keep it though. Personally, I’m quite fond
of it, but who knows what I’ll think in two weeks time. For now, it’s
awesome!
2025-08-21
Next button: div fiasco
Problem: Want clickable div, but also with links inside them. There’s multiple
links for a next for any one note, so I want clicking on the div to navigate
to the first listed note, and also be able to click on any one link inside the
div and go to that specific note.
Coming from React, you can imagine how baffled and frustrated I was when I put,
Turns out, you gotta get down on the ground and directly manipulating the DOM.
I’m fine with that, I do feel a little dirty though for some reason; better
wash my hands. What I have a problem with is the way they did it. I was gasping
in horror when I saw that they’re writing JS code in strings, that’s too much
for my leaning-on-autocomplete-to-code mind. I’m really glad they had another
method to inject JS by inlining, still jank, but better than just strings.
🗣️ Yap
I hope one day I’ll be enlightened enough to code just from regular, plain
strings without the seasoning from an LSP, maybe one day I’ll try coding on
vanilla vim for a month just to try it out.
Anyways, I tried it and my first attempt was jank as hell. It worked on initial
load, but it was inconsistent. Navigating rapidly between the links, scrolling
down a page, then clicking the button doesn’t work,
I suspect it’s because the event listener wasn’t attached after
navigation.
First attempt: footerRef.inline.ts
const refNavs = [ document.getElementById("ref-nav-next"), document.getElementById("ref-nav-prev"),]const onClickRefNav = (refNav: HTMLElement | null) => { if (!refNav) return const secondChild = refNav.children.item(1) as HTMLElement if (!secondChild) return const firstRef = secondChild.firstElementChild as HTMLAnchorElement document.location.href = firstRef.href}for (const refNav of refNavs) { if (refNav) { refNav.onclick = () => onClickRefNav(refNav) }}
But suddenly, a great idea came into my mind, “What if I just wrap the whole
damn div in an anchor tag! Then I wouldn’t need to do JS!” And so I did, but
then I got frustrated again when this happened,
The frick? The anchor tag got relegated as a sibling instead of wrapping around
the damn div like I expected it to! Why didn’t this work???
Turns out, there’s a snag with wrapping an achor tag within another anchor tag,
which is obvious in hindsight; not so much while I was in the thick of it. It
took me hours of frustration, grumbling, and giving up for the last time to
find out that browsers simply don’t allow nested <a> tags.
SUCCESS
for (const el of document.querySelectorAll<HTMLDivElement>(".ref-nav")) { el.addEventListener("click", (e) => { // If the click wasn't on a child <a>, follow the default link if (!(e.target as HTMLElement).closest("a")) { const url = el.dataset.defaultLink if (url) window.location.href = url } })}
And so, I leaned on Gippity instead and he made a beautiful snippet that worked
wonders. Now, everything is right with the world and I’m happy again,
Thank you, Gippity, you saved me hours of pain.
edit: Nevermind...
Turns out, it was laden with the same problem of the event listener not
attaching when navigating rapidly. For those keened eye of you may have
noticed, there’s a little glitch on each click. That’s the fullpage reload
from my sledgehammer solution: Turn off SPA.
2025-08-20
Deployment CI
Finally! The bloody pipeline is working…
And look!
We’re online. The machine works! Couple of lessons learned,
Don’t forget to copy the public SSH key to the server — the one you’ve
just generated for the GitHub Actions Runner
403 Forbidden — look at the scp target directory, double check by ssh-ing
into the server and ls
Reload Nginx with passwordless sudo — because normally you require password
access to execute any sudo commands, we need to disable that for the specific
command
sudo visudo# opens up editor, put the following on the LAST LINEusername ALL=(ALL) NOPASSWD: /bin/systemctl reload nginx
IMPORTANT
Make bloody sure you put that on the LAST LINE, sequence matters in sudoers.
I lost hours to this…
Other than that, it’s time to try out the first automated deployment with npx quartz sync.
Next Button
Adding a next button is getting bigger and more complicated than I initially
thought.
I was just going to put everything in one component, but then my React mind
kicked in and I started to componentize everything to avoid duplicating code.
Then, I started to think about types, where to put things, separating
stylesheets for the components, breaking things down… it’s starting to feel
like a second job now…
So far,
Components
FooterRef — main afterBody housing the references
RefNav— the “buttons,” handles the listing of links and linking proper files/externals
Sytlesheets
footerRef.scss — FooterRef
refNav.scss — RefNav
util.scss — added a couple util classes
Utils
refNav.ts — util functions
That’s it. I’m sick of QuartzComponent and QuartzComponentConstructor, it’s
so bloated for my usecase. I’m just gonna lean on my React experience and just
make a simple component.
edit: it's turning out pretty good.
although the annoyingly enough, the stylesheet is passed down through the
parent component—FooterRef—instead of imoprted directly in RefNav.