{"slug": "an-iframe-that-will-not-reload-when-mounted-on-the-page-again-based-on-src", "title": "An iframe that will not reload when mounted on the page again (based on `src`).", "summary": "The article presents a Vue.js component called `IframeKeepAlive.vue` that prevents iframes from reloading when they are re-mounted on a page by storing iframe instances in a global Map and reusing them based on a unique `id` prop. The component creates the iframe once, appends it to the document body, and simply hides or shows it during mount/unmount cycles, only updating the `src` if it changes. This approach maintains the iframe's state and avoids unnecessary reloads, improving performance for persistent embedded content.", "body_md": "IframeKeepAlive.vue\n\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      \nLearn more about bidirectional Unicode characters\n\n \n    Show hidden characters\n\n<script lang=\"ts\">\n\nconst iframes = new Map<string, { iframe: HTMLIFrameElement, src: string }>()\n\n</script>\n\n<script lang=\"ts\" setup>\n\nimport { useAttrs, ref, shallowRef, watchEffect, onMounted, onBeforeUnmount } from 'vue'\n\nimport { useElementBounding } from '@vueuse/core'\n\ndefineOptions({\n\n  inheritAttrs: false,\n\n})\n\nconst props = defineProps<{\n\n  id: string\n\n  src: string\n\n  class?: any\n\n  iframeClass?: any\n\n}>()\n\nconst attrs = useAttrs()\n\nconst wrapper = ref<HTMLDivElement>()\n\nconst iframe = shallowRef<HTMLIFrameElement | undefined>()\n\nconst bounds = useElementBounding(wrapper)\n\nwatchEffect(() => {\n\n  if (iframe.value) {\n\n    iframe.value.style.top = `${bounds.top.value}px`\n\n    iframe.value.style.left = `${bounds.left.value}px`\n\n    iframe.value.style.width = `${bounds.width.value}px`\n\n    iframe.value.style.height = `${bounds.height.value}px`\n\n  }\n\n})\n\nonMounted(() => {\n\n  const saved = iframes.get(props.id)\n\n  iframe.value = saved?.iframe\n\n  if (!iframe.value) {\n\n    iframe.value = document.createElement('iframe')\n\n    iframe.value.style.position = 'fixed'\n\n    iframe.value.src = props.src\n\n    iframe.value.classList.add('w-full', 'h-full', 'border-0')\n\n    if (props.iframeClass) {\n\n      if (typeof props.iframeClass === 'string') {\n\n        iframe.value.classList.add(...props.iframeClass.split(/\\s+/))\n\n      }\n\n      else {\n\n        iframe.value.classList.add(...props.iframeClass)\n\n      }\n\n    }\n\n    for (const [key, value] of Object.entries(attrs)) {\n\n      iframe.value.setAttribute(key, String(value))\n\n    }\n\n    iframes.set(props.id, { iframe: iframe.value, src: props.src })\n\n    document.body.appendChild(iframe.value)\n\n  }\n\n  else if (props.src !== saved?.src) {\n\n    iframe.value.src = props.src\n\n  }\n\n  iframe.value.style.display = 'block'\n\n})\n\nonBeforeUnmount(() => {\n\n  if (iframe.value) {\n\n    iframe.value.style.display = 'none'\n\n  }\n\n})\n\n</script>\n\n<template>\n\n  <div ref=\"wrapper\" :class=\"props.class\" />\n\n</template>\n\nUsage.vue\n\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      \nLearn more about bidirectional Unicode characters\n\n \n    Show hidden characters\n\n<\ntemplate\n>\n\n  <\nIframeKeepAlive\n\n \nid\n=\n\"\niframe-1\n\"\n\n \nsrc\n=\n\"\nhttps://vuejs.org\n\"\n\n  />\n\n</\ntemplate\n>", "url": "https://wpnews.pro/news/an-iframe-that-will-not-reload-when-mounted-on-the-page-again-based-on-src", "canonical_source": "https://gist.github.com/Akryum/5ef3c30e0c43a57135ad1e18d54cc03a", "published_at": "2024-01-02 10:01:55+00:00", "updated_at": "2026-05-23 22:05:48.349326+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["Vue", "VueUse"], "alternates": {"html": "https://wpnews.pro/news/an-iframe-that-will-not-reload-when-mounted-on-the-page-again-based-on-src", "markdown": "https://wpnews.pro/news/an-iframe-that-will-not-reload-when-mounted-on-the-page-again-based-on-src.md", "text": "https://wpnews.pro/news/an-iframe-that-will-not-reload-when-mounted-on-the-page-again-based-on-src.txt", "jsonld": "https://wpnews.pro/news/an-iframe-that-will-not-reload-when-mounted-on-the-page-again-based-on-src.jsonld"}}