{"id":15369837,"url":"https://github.com/electrovir/interlocking-iframe-messenger","last_synced_at":"2026-02-15T01:06:02.435Z","repository":{"id":142529176,"uuid":"612403141","full_name":"electrovir/interlocking-iframe-messenger","owner":"electrovir","description":"Handle messaging to and from an iframe without race conditions.","archived":false,"fork":false,"pushed_at":"2025-02-06T18:32:11.000Z","size":923,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-13T07:46:14.283Z","etag":null,"topics":["iframe","message","messenger","postmessage"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/interlocking-iframe-messenger","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/electrovir.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-CC0","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-10T21:47:59.000Z","updated_at":"2025-02-06T18:32:14.000Z","dependencies_parsed_at":"2024-10-16T10:41:02.327Z","dependency_job_id":"5575bd68-32ad-4d30-9f8c-b5fa41a51f35","html_url":"https://github.com/electrovir/interlocking-iframe-messenger","commit_stats":{"total_commits":51,"total_committers":1,"mean_commits":51.0,"dds":0.0,"last_synced_commit":"e10be7f23bea397f292cdff80480dd7dffd29357"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/electrovir/interlocking-iframe-messenger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/electrovir%2Finterlocking-iframe-messenger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/electrovir%2Finterlocking-iframe-messenger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/electrovir%2Finterlocking-iframe-messenger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/electrovir%2Finterlocking-iframe-messenger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/electrovir","download_url":"https://codeload.github.com/electrovir/interlocking-iframe-messenger/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/electrovir%2Finterlocking-iframe-messenger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29463617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-15T01:01:38.065Z","status":"ssl_error","status_checked_at":"2026-02-15T01:01:23.809Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["iframe","message","messenger","postmessage"],"created_at":"2024-10-01T13:38:54.382Z","updated_at":"2026-02-15T01:06:02.419Z","avatar_url":"https://github.com/electrovir.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# interlocking-iframe-messenger\n\nPost messages to a child iframe while accounting for race conditions.\n\nPotential race conditions that are handled include:\n\n-   [x] waiting for the iframe to load\n-   [x] waiting for the iframe content to finish loading (yes, this is different from the condition above)\n-   [x] any lag in the iframe content from scripts\n-   [x] anything else that may cause an iframe to miss a message\n\nCurrently this only works as the parent content being the communication initiator. The child only responds to messages from the parent, it doesn't send messages of its own accord. If the parent is ready for specific data from the child, it must send a message to request that data.\n\nSee a simple live demo at [electrovir.github.io/interlocking-iframe-messenger](https://electrovir.github.io/interlocking-iframe-messenger).\n\n## install\n\n```bash\nnpm i interlocking-iframe-messenger\n```\n\n## usage\n\nFollow the headings below in order for a full usage example.\n\n### setup\n\nFirst, setup an iframeMessenger. Make sure to provide a list of allowed origins for security purposes. (If you do not provide any, warnings will be logged in your console.)\n\nMake sure to provide a generic type to `createIframeMessenger` so that your message data is typed. The given type should match a similar structure to `MessageData` shown below.\n\n\u003c!-- example-link: src/readme-examples/messenger-setup.example.ts --\u003e\n\n```TypeScript\nimport {createIframeMessenger, IframeMessageDirectionEnum} from 'interlocking-iframe-messenger';\n\nexport enum MessageTypeEnum {\n    RequestDataFromChild = 'request-data-from-child',\n    SendDataToChild = 'send-data-to-child',\n}\n\nexport type MessageData = {\n    [MessageTypeEnum.RequestDataFromChild]: {\n        [IframeMessageDirectionEnum.FromParent]: undefined;\n        [IframeMessageDirectionEnum.FromChild]: string;\n    };\n    [MessageTypeEnum.SendDataToChild]: {\n        [IframeMessageDirectionEnum.FromParent]: string;\n        [IframeMessageDirectionEnum.FromChild]: undefined;\n    };\n};\n\nexport const myIframeMessenger = createIframeMessenger\u003cMessageData\u003e();\n```\n\n### send a message to the child iframe\n\nUse the `.sendMessageToChild()` method on `IframeMessenger` to send messages to the child iframe.\n\nBased on the given message type, if data is expected from the child iframe, a `verifyChildData` function must be provided. This will get called internally by `sendMessageToChild` and if `verifyChildData` returns false, `sendMessageToChild` will fail.\n\n\u003c!-- example-link: src/readme-examples/parent-send-message.example.ts --\u003e\n\n```TypeScript\nimport {MessageTypeEnum, myIframeMessenger} from './messenger-setup.example.js';\n\nasync function sendMyMessage(iframeElement: HTMLIFrameElement) {\n    const childValue: string = (\n        await myIframeMessenger.sendMessageToChild({\n            iframeElement,\n            childOrigin: 'https://example.com',\n            type: MessageTypeEnum.RequestDataFromChild,\n            data: undefined,\n            // if data is expected from the child, a verifyChildData function must be provided\n            verifyChildData(childData) {\n                return typeof childData === 'string';\n            },\n        })\n    ).data;\n\n    // this will end up logging the string value that the child generated\n    console.log({childValue});\n}\n\nsendMyMessage(\n    // pass in a reference to your iframe\n    document.querySelector('iframe')!,\n);\n```\n\n### listen to messages from the parent\n\nUse `.listenForParentMessages()` in the child iframe source code to properly handle parent messages and respond when required. Notice that, in the example below, when the parent is expecting a response (when the type is `MessageTypeEnum.RequestDataFromChild`), the listener directly returns the data which the parent is expecting and waiting for.\n\n\u003c!-- example-link: src/readme-examples/child-listen-to-messages.example.ts --\u003e\n\n```TypeScript\nimport {MessageTypeEnum, myIframeMessenger} from './messenger-setup.example.js';\n\nmyIframeMessenger.listenForParentMessages({\n    parentOrigin: 'https://example.com',\n    listener: (message) =\u003e {\n        if (message.type === MessageTypeEnum.RequestDataFromChild) {\n            // send the data that the parent is expecting\n            return 'some string from the child';\n        } else if (message.type === MessageTypeEnum.SendDataToChild) {\n            const parentData = message.data;\n\n            // process parentData here\n        }\n\n        return undefined;\n    },\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felectrovir%2Finterlocking-iframe-messenger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felectrovir%2Finterlocking-iframe-messenger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felectrovir%2Finterlocking-iframe-messenger/lists"}