[UserScript] WK Flagger

:warning: This is a third-party script/app and is not created by the WaniKani team. By using this, you understand that it can stop working at any time or be discontinued indefinitely.

This is a very simple userscript (though poor gorbit, then he quickly reconsidered), if you’ve ever used the flag feature of Anki, it’s exactly that.

I don’t care what you need to say, I just collect userscripts like pokémon

In that case, here are your download links:
Visual Guide on Installing Userscripts
WaniKani Open Framework Installation Instructions, because this script needs it
Link to the userscript itself
CW: a very cute cat

But what is this really?

The userscripts add a cute flag during reviews, right next to the statistics:

Clicking on the flag reveals a whole array of other cute flags:

Choosing one will flag that review with that colour, and whenever the item comes back up in the future, the flag will remind you that it is in fact an important item for whatever reason.

What is the system behind the colours?

That is in fact the fun part - there is no system. It’s there for you to make one up. When I used this feature in Anki, I, for example, marked items where I had trouble with the reading one colour, items where I had trouble with the meaning another colour, and items that had no right to be in my review queue, as if I had never even seen them before, well, those got a third colour. (Then I promptly started marking them with the same flag, because systems are hard to memorize).

The flags aren’t good for making items you just can’t memorize suddenly easy, but they can make your brain pull the emergency brake whenever they come up, so you can slow down and not answer 鼻血 with はなち. Don’t try to make a system, where “blue means this thing is read こう”, that would be easier to drill in without the colour.


By default, the script comes with 5 flag colours included (besides the empty one). These are “red”, “green”, “blue”, “yellow”, and obviously, “medium spring green”. However both the count and the colour are easy to customize, in case you didn’t take my previous paragraph seriously, or maybe you are colour blind.

Customizing the colours

Open up the script’s code, fight your hatred, fear of disgust of JavaScript down, and navigate to these lines:

The part before the colon is the id of the colour used for storing them, make sure these are unique, while the part between the quotation marks is the colour value. This accepts anything CSS accepts, but most commonly you will either fill these with hex colour codes starting with a hashtag, or with a standard web color name.

Make sure, each line ends with a comma!

Less important info

The userscript supports the Breeze Dark 2 theme out of the box.

If you find a bug, or you have a feature request, while I don’t promise anything, do leave a message about it and I’ll try to look into it.


This is exactly what I need right now. I am accumulating leeches where even just 8hrs after seeing the right answers I have already forgotten everything about them. These flags might help to kickstart my brain a little so I have a better chance at remembering them. Awesome little script :3

1 Like

Alrighty, first small issue encountered. If you use Confusion Guesser, the flags end up behind it.


[Note to self… figure out what the heck is up with the colors on Confusion Guesser and maybe add a way to dismiss the flyout]

Edit: I did indeed add a hotkey for dismissing the overlay so the issue is solved for me. Not sure what you’d be able to do, maybe this really does have to be solved on Confusion Guesser’s end.

You didn’t ask but personally what I do when that happens is that I use undo to pass these words even if I get them wrong then a few weeks later (say when they reach master or whatever) I fail them again and give them another try.

There are so many things to learn, if I feel like one specific word just won’t stick I’d rather not waste my time (and increase my frustration) by repeating it multiple times on a daily basis without progress.

Thanks for the tip! I actually already do this, but instead of letting them get to master my rule is I get them to guru 1, guru 2 if I felt like I was close enough, but if I get them wrong from there I can’t pass them, they have to advance naturally. And this has lead to a few kanji and vocab sitting in apprentice for days at a time where I really struggle to remember anything about them (neither WaniKani mnemonics nor ones I make myself seem to stick, sometimes the radicals are just too disconnected from the meaning). It’s frustrating for sure, but I’d rather suffer until they sink in (and besides, I will likely forget once they reach master naturally anyway; master and enlightened are where I see the majority of my mistakes).

1 Like

I’ll look into what I can do, I have an idea I can start with, but it will need a bit of coding

Just discovered that the script isn’t saving the flags once you exit a review session. This is because it will always perform the file_cache load regardless of what page it’s on, then try to update the shown flag, which fails because we are not on the review page, triggering the catch and resetting the database.

Since as far as I can tell this script does not need to run on any pages outside of reviews, the matches should be changed to just the review url, the parts of the code that check for what url we’re on can then maybe be removed, and perhaps most importantly, the error handling for an issue in the file_cache load callback should not reset the cache (unless the error is specifically identified as a corruption in the cache).

That isn’t quite possible, at least as far as I know, sInce technically wk doesn’t do a full reload when you enter a session, it just does a turbo navigation, so I need to listen to that and load the flag changes when entering reviews.

Found the bug and now it’s fixed, and I tried to make sure that the reset only happens, if the loading itself throws an error. (so hopefully only when the key isn’t there)

No, you’re right, I just mistakenly believed the navigation from the dashboard to reviews was a turbo load. Turns out it’s not. But going from, say, an item page to reviews via the top nav is. Even the Open Framework script menu gets borked by this.

I think script managers are able to handle this specific case because I’ve changed a number of scripts to only match the review url and they work just fine; that is, the important thing is the url changed, and the script manager is looking for this, and when it matches it injects the script.

Scripts I’ve changed in this way that work: Kanji Review Vocabulary List, Detailed SRS Popups, (made, not changed:) Visible SRS Stage – this one you can see right next to the flag in my earlier post.

1 Like

Yep, one of the issues that needs to be dealt with since that update. And tbh, this way, once the user is on a page like that, at least the data stays loaded and you don’t need to wait until it loads.

Ok, I tried to test it in the same scenario that made me realize why I was wrong, and it still wasn’t loading the flag in (and Kanji Review Vocab List and my Visible SRS Stage were also not loading even after I mimicked what you did). It took the past 4 hours of me troubleshooting, but thanks to realizing that Later Crabigator does successfully insert itself in this scenario, I was able to learn how to modify the scripts to get them to work too.

You can check out Later Crabigator for the code, but the general idea is that instead of listening for “turbo:load”, you listen for “turbo:before-render” and create a mutation observer to observe changes to the child list of the new body. Once the change is confirmed, we disconnect the observer and call whatever initialization/setup function needs to run first. In that function we perform our url check.

Edit: Also I had to add if (window.location.pathname !== "/subjects/review") return; to updateShownFlag because the promise callback was running on the dashboard and then an error got thrown.

1 Like

Btw, haven’t looked at this in a bit, I’ve been using the script without an issue for a bit now, do you still get the problem with it?

Oh uh, I wouldn’t be able to tell, sorry ^ ^

Pretty much immediately after that I set off to start making major changes to it because of one issue I was having: I couldn’t remember the meanings of all the flags I set, and I didn’t like having to look in some external place while doing a review. So I have been slowly working on adding flag management and a way to easily display the flag meanings you give during reviews (also making it so you can set a color per question type, as there are colors I want for meanings and readings separately and some colors I want to apply to both question types).

I’ve made a lot of changes so I can’t evaluate how the current version of the script is working (and can’t downgrade either because I’ve changed how the cache file is structured: storing available flags and the information associated with a flag name being more than just a color now). It’s been a really fun project! Teaching me lots of things like designing a settings dialog, basic CRUD and state management, thinking about UI and UX… I’m excited to share the finished result.

Edit: I did just test again and can confirm that the use of the turbo:load event listener does not work. The flag UI still does not get inserted. As a reminder, starting reviews from the dashboard is not a turbo load. To test whether the turbo handling is working, first go to a page like the pleasant vocabulary and then start a review from the top nav bar. One easy way to know you’ve got a turbo load into reviews is to see that the open framework menu will be broken (at least for me on Firefox).

1 Like