How to "pre-load" the <iframe> HTML tags in the BACK of cards

I use the <iframe> HTML tag to include web-content within the back of my cards.

The front card shows a phrase, and the back side shows the definition in the German Wiktionary. However, the website is a slow to appear due to my low internet speed.

Is it possible to configure Anki so that whenever the FRONT side of a card appears, the website in the BACK of the card begins to automatically load in the background ?

Any good ideas @kleinerpirat ? :smiley:


PS. If you want to add the Wiktionary in the back of your cards just paste this code in your back template:

<iframe src="https://en.wiktionary.org/wiki/{{Front}}" style="height: 100vh; width:100%;" seamless="seamless"></iframe>

Just change the “en.wiktionary” to your target language (eg. German= “de.wiktionary”)

TBH, I think the most straightforward solution would simply be to make a local copy of the pages you want to load. This can probably be automated so that it’s quick and easy to do on a bunch of cards. Also, this will work offline, be faster, require less hassle and won’t suddenly break if the german wikitionary suddenly changes its “API” (although this doesn’t seem that likely — but still, that’s not impossible).

If you still want to use iframes, it’s a bit tricky because when you review a card, you don’t have a single page that is “updated” when you want to see its back version; it’s actually two different pages, so anything that happened (or was loaded) in the former won’t be accessible in the latter, in theory. In practice, there is a way to pass information, but, AFAIK, it’s not reliable on all platforms. That way is anki persistence, which allows you to “store” a JS variable in a persistent storage, and access it whenever you want. I am not a web developer, so I couldn’t tell you how to store the iframe in a JS variable, and re-use it later on, but I think that’s the way to go.

1 Like

A workaround to increase the speed of loading the Wiktionary is to use the mobile version ! The page will be like 10 times smaller…

https://en.m.wiktionary.org/wiki/black 176KB
https://en.wiktionary.org/wiki/black 1.16MB

Template: <iframe src="https://en.m.wiktionary.org/wiki/{{Front}}" style="height: 100vh; width:100%;" seamless="seamless"></iframe>

2 Likes

I wonder if simply putting an invisible iframe on the front would help. Stuff should get cached

1 Like

That would only work if you had {{FrontSide}} in your back template, wouldn’t it?

Browsers cache network requests in order to not re-download everything every time. This cache may persist even across reboots. Not sure if Anki’s web views do caching, and not sure if Wikipedia doesn’t instruct not to cache its pages, but it’s an easy thing to just try and see if it just magically works eh

3 Likes

That seems like the most fragile way to solve this issue :stuck_out_tongue: even if it magically worked out today, it may very well magically stop working tomorrow, because cache is usually not meant to be kept forever (at least for web browsers), and because in general you should never rely on the fact that cache has not been purged (exactly because cache is cache, and is allowed to be purged).

It seems that it does not work with an invisible iframe, but it is a good idea ! Thanks for your kind offer of help :smiley:

By the way, It seems that Anki does not support catching…

because cache is usually not meant to be kept forever (at least for web browsers)

My idea was is that you put an invisible frame in the front of the card, and a visible one in the back. This way it has to be cached for a few seconds only.

By the way, It seems that Anki does not support catching…

I just tried and it does. The cache does not persist between runs, but definitely works between front and back. How did you make it invisible? display: none may prevent the engine from loading elements. I put this in the front of my card:

<iframe src="https://emoji.discourse-cdn.com/twitter/smiley.png?v=12" style="opacity: 0"></iframe>

And in the back I put the same but without style. After pressing answer, Inspector shows this:

(Image was requested thrice because my back includes my front)

Note that if you don’t use iframe but a direct link to an image in the back of your card, Anki prefetches it when you open the front. How wise of Anki!

With iframe, while the trick above works, the page has to-rerender. It will also re-run all the javascript, etc. Might be slow even though it doesn’t use data. I wonder if there’s a way to save the element while in front, and reattach when in the back.

4 Likes

You could append the iframes to an element outside of #qa (e.g. document.body), so they won’t get refreshed on the backside. Then hide them on the front with CSS.

Front

<script>
(() => {
  const urls = [
    "https://example.com/widget.html",
    "https://www.wikipedia.org",
  ]

  let container = document.getElementById("iframe-container");
  if (!container) {
    container = document.createElement("div");
    container.setAttribute("id", "iframe-container");
    document.body.append(container);
  }

  container.classList.add("front");
  container.innerHTML = "";

  urls.forEach((url) => {
    const iframe = document.createElement("iframe");
    iframe.src = url;
    container.appendChild(iframe);
  });
})();
</script>

Back

<script>
(() => {
  document.getElementById("iframe-container").classList.remove("front");
})();
</script>

CSS

.front iframe {
  visibility: hidden;
  height: 0;
}

(display: none prevents the iframe from loading content, hence the visibility + height combo)

This should work for Anki Desktop, AnkiWeb and AnkiMobile, but not for AnkiDroid.

3 Likes

Ah ok I didn’t understood what you wanted to do the first time. I though you meant reviewing once would store the iframe in the cache for some time, so on the next review it would be faster…