├── .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 |
--------------------------------------------------------------------------------