├── .eslintcache ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt └── src ├── App.css ├── App.js ├── App.test.js ├── components ├── IframeChild.jsx ├── IframeParent.jsx ├── WindowChild.jsx └── WindowParent.jsx ├── index.css ├── index.js ├── logo.svg ├── reportWebVitals.js └── setupTests.js /.eslintcache: -------------------------------------------------------------------------------- 1 | [{"/Users/jaimelozano/Desktop/post-message/src/index.js":"1","/Users/jaimelozano/Desktop/post-message/src/App.js":"2","/Users/jaimelozano/Desktop/post-message/src/reportWebVitals.js":"3","/Users/jaimelozano/Desktop/post-message/src/components/IframeParent.jsx":"4","/Users/jaimelozano/Desktop/post-message/src/components/IframeChild.jsx":"5","/Users/jaimelozano/Desktop/post-message/src/components/WindowParent.jsx":"6","/Users/jaimelozano/Desktop/post-message/src/components/WindowChild.jsx":"7"},{"size":504,"mtime":1610301761915,"results":"8","hashOfConfig":"9"},{"size":749,"mtime":1610306278471,"results":"10","hashOfConfig":"9"},{"size":362,"mtime":1610301572518,"results":"11","hashOfConfig":"9"},{"size":992,"mtime":1610318360520,"results":"12","hashOfConfig":"9"},{"size":638,"mtime":1610318275956,"results":"13","hashOfConfig":"9"},{"size":1042,"mtime":1610318969627,"results":"14","hashOfConfig":"9"},{"size":685,"mtime":1610318617070,"results":"15","hashOfConfig":"9"},{"filePath":"16","messages":"17","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"18"},"gsqgbo",{"filePath":"19","messages":"20","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"18"},{"filePath":"21","messages":"22","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"18"},{"filePath":"23","messages":"24","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"25","messages":"26","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"27","messages":"28","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"29","messages":"30","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Users/jaimelozano/Desktop/post-message/src/index.js",[],["31","32"],"/Users/jaimelozano/Desktop/post-message/src/App.js",[],"/Users/jaimelozano/Desktop/post-message/src/reportWebVitals.js",[],"/Users/jaimelozano/Desktop/post-message/src/components/IframeParent.jsx",[],"/Users/jaimelozano/Desktop/post-message/src/components/IframeChild.jsx",[],"/Users/jaimelozano/Desktop/post-message/src/components/WindowParent.jsx",["33"],"/Users/jaimelozano/Desktop/post-message/src/components/WindowChild.jsx",[],{"ruleId":"34","replacedBy":"35"},{"ruleId":"36","replacedBy":"37"},{"ruleId":"38","severity":1,"message":"39","line":1,"column":17,"nodeType":"40","messageId":"41","endLine":1,"endColumn":23},"no-native-reassign",["42"],"no-negated-in-lhs",["43"],"no-unused-vars","'useRef' is defined but never used.","Identifier","unusedVar","no-global-assign","no-unsafe-negation"] -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Post Messages to iFrame and Window in React 2 | 3 | Hello guys! in this code you'll find how to communicate between parent windows with child iframes and windows using React. Please watch the YouTube video if you're interested in knowing how it works. 4 | 5 | Youtube video link: https://www.youtube.com/watch?v=LCZ7PcYGxew 6 | 7 | Enjoy! 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "post-message", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.8", 7 | "@testing-library/react": "^11.2.3", 8 | "@testing-library/user-event": "^12.6.0", 9 | "react": "^17.0.1", 10 | "react-dom": "^17.0.1", 11 | "react-router": "^5.2.0", 12 | "react-router-dom": "^5.2.0", 13 | "react-scripts": "4.0.1", 14 | "web-vitals": "^0.2.4" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": [ 24 | "react-app", 25 | "react-app/jest" 26 | ] 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.2%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jl0zano/ReactPostMessage/6af7f3c9ea2a487b6c4399d6f3e0f495e921a0a2/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jl0zano/ReactPostMessage/6af7f3c9ea2a487b6c4399d6f3e0f495e921a0a2/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jl0zano/ReactPostMessage/6af7f3c9ea2a487b6c4399d6f3e0f495e921a0a2/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import { BrowserRouter, Route, Switch } from "react-router-dom"; 2 | import { IframeParent } from "./components/IframeParent"; 3 | import { IframeChild } from "./components/IframeChild"; 4 | import { WindowParent } from "./components/WindowParent"; 5 | import { WindowChild } from "./components/WindowChild"; 6 | export const App = () => { 7 | return ( 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /src/components/IframeChild.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | export const IframeChild = () => { 3 | const [recievedMessage, setRecievedMessage] = useState(""); 4 | 5 | const sendMessage = () => { 6 | window.parent.postMessage("Hi dad!", "http://localhost:3000"); 7 | }; 8 | 9 | useEffect(() => { 10 | window.addEventListener("message", function (e) { 11 | if (e.origin !== "http://localhost:3000") return; 12 | setRecievedMessage("Got this message from parent: " + e.data); 13 | }); 14 | }, []); 15 | 16 | return ( 17 |
18 |

Child iFrame

19 | 20 |

{recievedMessage}

21 |
22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /src/components/IframeParent.jsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useEffect, useState } from "react"; 2 | export const IframeParent = () => { 3 | const iFrameRef = useRef(null); 4 | const [recievedMessage, setRecievedMessage] = useState(""); 5 | 6 | const sendMessage = () => { 7 | if (!iFrameRef.current) return; 8 | iFrameRef.current.contentWindow.postMessage( 9 | "Hello son!", 10 | "http://localhost:3000" 11 | ); 12 | }; 13 | 14 | useEffect(() => { 15 | window.addEventListener("message", function (e) { 16 | if (e.origin !== "http://localhost:3000") return; 17 | setRecievedMessage("Got this message from child: " + e.data); 18 | }); 19 | }, []); 20 | 21 | return ( 22 |
23 |

Parent iFrame

24 | 31 | 32 |
33 |
34 | 35 | 42 | 43 |

{recievedMessage}

44 |
45 | ); 46 | }; 47 | -------------------------------------------------------------------------------- /src/components/WindowChild.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | export const WindowChild = () => { 3 | const [recievedMessage, setRecievedMessage] = useState(""); 4 | 5 | const sendMessage = () => { 6 | window.opener.postMessage("Hi dad!", "http://localhost:3000"); 7 | }; 8 | 9 | useEffect(() => { 10 | window.addEventListener("message", function (e) { 11 | if (e.origin !== "http://localhost:3000") return; 12 | setRecievedMessage("Got this message from parent: " + e.data); 13 | }); 14 | }, []); 15 | 16 | return ( 17 |
18 |

Child Window

19 | 20 |

{recievedMessage}

21 |
22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /src/components/WindowParent.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | export const WindowParent = () => { 3 | const [recievedMessage, setRecievedMessage] = useState(""); 4 | 5 | let childWindow; 6 | 7 | const sendMessage = () => { 8 | if (!childWindow) return; 9 | childWindow.postMessage("Hello son!", "http://localhost:3000"); 10 | }; 11 | 12 | useEffect(() => { 13 | window.addEventListener("message", function (e) { 14 | if (e.origin !== "http://localhost:3000") return; 15 | setRecievedMessage("Got this message from child: " + e.data); 16 | }); 17 | }, []); 18 | 19 | const openWindow = () => { 20 | childWindow = window.open( 21 | "http://localhost:3000/window-child/", 22 | "childWindow", 23 | "width=500,height=500" 24 | ); 25 | }; 26 | 27 | return ( 28 |
29 |

Parent Window

30 | 31 | 32 |
33 |
34 | 35 | 42 | 43 |

{recievedMessage}

44 |
45 | ); 46 | }; 47 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import { App } from "./App"; 5 | import reportWebVitals from "./reportWebVitals"; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById("root") 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | --------------------------------------------------------------------------------