ProxyFeed devlog: locked tag - logic and implementation
I don't write posts like this in one sitting. I usually start a rough draft, then come back to it while working on the actual feature — testing, debugging, refining the logic. This one is about the <podcast:locked>
tag.
The <podcast:locked>
tag is part of the Podcasting 2.0 spec. Its purpose is simple: a hosting provider can set locked="yes"
in the feed to indicate that the podcast should not be imported by other platforms. It’s not a security feature — it's more of a courtesy signal between hosts. But since there's a spec insisting that hosts respect it, we also need to support it.
It’s similar to how we handle the <podcast:funding>
tag:
- If the original feed already contains a
<podcast:locked>
tag, we leave it as-is and pass it through. - If the original feed doesn’t contain the tag and the user has enabled it in their settings, we insert it into the proxy feed.
There’s a slight twist. Unlike the funding tag, the <podcast:locked>
tag should always be present in the proxy feed. Even if the user disables it, we still include it — just with locked="no"
.
At first glance, it might seem like disabling the tag should remove it entirely. That’s also a valid approach, but I’ve chosen to follow the spec as intended: the tag stays, and only its value changes.
I’ve decided that each Podcasting 2.0 tag in ProxyFeed will have its own database table. This makes the structure a bit more complex (there will be many tables), but it keeps things clean and easy to maintain.
It took me exactly two days to implement this feature. The second half of the second day went into debugging. The core of the problem was that the <podcast:locked>
tag accepts "yes" or "no" as values, but I implemented the toggle as true/false.
In theory, that should work. But I had another condition: if the original feed lacks the tag, we should insert it into the proxy feed with the value "yes". The logic broke when I switched the value to "no".
After digging deeper, I discovered that somewhere along the way, Node.js automatically converts "yes" to true
and "no" to false
, and vice versa. That broke everything.
So I had to redo it all. Now the database stores the value as a string, not a boolean. That was the only way to get the logic out of this maze.
Now, ProxyFeed handles the <podcast:locked>
tag like this:
- If the original feed includes the tag, we pass it through unchanged. In the settings UI, we indicate that the tag comes from the original and cannot be modified.
- If the tag is missing from the original feed, we insert it with
locked="yes"
by default. The user can change this to"no"
if they don’t want to block imports.
Published on July 17, 2025