Hyperlink IDs aren't static?

I’ve been making adjustments a feature in my plugin that involves creating custom hyperlinks, and attempting to use the hyperlink IDs to identify and manipulate them. When creating a new custom hyperlink the plugin stores the ID associated with the hyperlink to a json file so that it can be referenced again. This all works but i’ve hit a huge roadblock: hyperlink IDs change. From what i can tell the IDs only change when you cancel a story check out, even if nothing in the story changed. How can i work with this programmatically? i can’t identify the hyperlinks anymore if the ID in InDesign has changed from what i have stored.

in the screen shot below it can be seen that any hyperlink’s ID in the same story is changing when cancelling a story check out. In the example, “American National Standards Institute (ANSI)@18” is in the story being checked out, then cancelling the check out, and “Pressure@16” is in a separate story that is not being changed:
Screenshot 2025-07-16 at 2.01.01 PM

Apparently (read: I did not verify) when you cancel checkout InDesign discards the story and rebuilds it from the associated assignment. From the C++ side I remember there are ways to preserve an ID for such scenarios, but I did not try whether that works. Even if it does, it apparently is not used in the particular case. File a bug report and wait until is fixed. Until then:

When you preserve your IDs in that json, also use insertLabel() on the hyperlink. They should survive even when the story is rebuilt. For obvious reasons that should happen before you create the assignment, and before you bet the farm on it verify that these labels are contained in your files.

If you’re desperate about existing data, have a peek at the .icml where the old IDs should be preserved in some attribute. Build a table in that order. The newly assigned hyperlink IDs should have the same order.

I’d wonder what else is lost on such a roundtrip, e.g. when a hyperlink text destination is within your rebuilt story, what happens to references from other stories …

Labels were what i determined to be the next step here to verify the hyperlinks after a cancel checkout. I’m planning to make a triple check to validate the hyperlinks now: 1st the hyperlink ID with itemByID(), if thats no good try .itemByName(), and finally try to identify by the label but that will be more laborious since there isnt a method to directly identify those. Thanks for the insight on stories being rebuilt on cancel checkout!

As it turns out, nope, the labels are being reset on Cancel Check Out as well. I tried two ways. First, insertLabel(key, value) but that seems to be reset and isn’t accessible by any means other that extractLabel(key) meaning i can’t actually access that property without running extractLabel() on every hyperlink. Second, i tried just hyperlink.label = string, which is accessible and i could add a prototype method for itemByLabel(), but again that gets resets on Cancel Check Out.

Did you attempt to write the labels to the assignment, as suggested above?

i don’t quite understand what you are saying here. I’m adding the labels to the hyperlinks that are created or already exist in a story that has been exported to .icml’s. what more could i do to “write the labels to the assignment”? Programmatically reading the stories XML doesn’t seem like a great idea, and events in the InDesign API are really lackluster so i can’t effectively detect a check in, check out, or cancel check out in order to know when to check that stuff.

There are plenty of scenarios where we might need to add a new hyperlink after stories have been exported, so if this methods relies on hyperlinks being created before stories are ever exported then thats not an option.

Ok, the issue is the “has been exported” as I suspected.

As I wrote with “desperate about existing data”, you have to detect the restore / cancel checkout happening, pick up the old IDs from the icml (where they hopefully still are) and the new ones where they arrived, then update your json accordingly to get back in sync. If it works at all - still assuming the order of the new IDs is related to the order within the icml.

As you mention new hyperlinks after the export, does that include hyperlink text destinations within the not-checked-out assignment? I would be surprised if that’s possible. I have to admit I haven’t worked much with hyperlinks, only recently from the user side where I found them a bit weird. To get more certainty I’d have to spend serious time beyond a forum post, so leaving it at that.

I’ve made a custom glossary system of hyperlinks thats forces a javascript function where the url should be to create interactive hoverable cards when exported to html “ebooks”.

But your comment before about writing to the story finally clicked with me and i tried the labels again, realizing i probably was making a fool of myself by not checking the story back in before attempting to test cancelling the checkout. Ill need to do more thorough testing but it seems that was the case. most likely the cancel check in was reverting data stored in the story back when i mistakenly assumed all the data was stored in the .indd, not in the .icmls.

1 Like