Embedding your Menutech menu on your website
Iframe embed
Paste the following HTML code anywhere on your website, where you want your iframe to be displayed:
<iframe src="ENTER YOUR MENU URL HERE" frameborder="0" style="overflow:hidden;width:100%;display:block;" height="100%" width="100%"></iframe>
✏️ Make sure to replace ENTER YOUR MENU URL HERE with the URL of your Menutech Digital Menu.
Enabling advanced features:
To ensure the iframe has exactly the height of its content, and to support more advanced features (setting the iframe to the full height to avoid scrolling, supporting image dialogues), paste this code anywhere on your website, or directly after the iframe element:
<script>
window.addEventListener(
"message",
function (event) {
if (event.data[0] === "setIframeHeight") {
var iframe = document.getElementsByTagName("iframe")[0];
iframe.height = event.data[1] + 1 + "px";
iframe.style.height = event.data[1] + 1 + "px";
} else if (event.data[0] == "requestHeightPosition") {
var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var iframe = document.getElementsByTagName("iframe")[0];
iframe.contentWindow.postMessage(["setParentHeight", height - 100], "*");
var scrollPosition = window.scrollY || document.documentElement.scrollTop;
iframe.contentWindow.postMessage(["setScrollPosition", scrollPosition], "*");
}
},
false
);
window.onload = function () {
var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var iframe = document.getElementsByTagName("iframe")[0];
iframe.contentWindow.postMessage(["setParentHeight", height - 100], "*");
var scrollPosition = window.scrollY || document.documentElement.scrollTop;
iframe.contentWindow.postMessage(["setScrollPosition", scrollPosition], "*");
};
window.onresize = function () {
var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var iframe = document.getElementsByTagName("iframe")[0];
iframe.contentWindow.postMessage(["setParentHeight", height - 100], "*");
};
window.onscroll = function () {
var scrollPosition = window.scrollY || document.documentElement.scrollTop;
var iframe = document.getElementsByTagName("iframe")[0];
iframe.contentWindow.postMessage(["setScrollPosition", scrollPosition], "*");
};
</script>
API-based embed
An API-based embed sits directly in your website and can be further styled by your webmaster. Place the following code anywhere on your website, where you would like the menu to display:
<div id="menutech-container"></div>
<script>
let mtUrl = 'ENTER YOUR MENU URL HERE';
document.addEventListener("DOMContentLoaded", function() {
fetch(mtUrl + '&embed=true')
.then(response => response.text())
.then(data => {
document.getElementById('menutech-container').innerHTML = data;
})
.catch((error) => {
console.error('Error:', error);
});
});
</script>
✏️ Make sure to replace ENTER YOUR MENU URL HERE with the URL of your Menutech Digital Menu.
ℹ To load the menu immediately, add the <script>...</script> element in your HTML header.
⚠️ The API-based embed does not include the header and collapsible footer.
Insulated embed
To insulate the embedded code and prevent any spillovers of styles and scripts, the menu can be embedded in a "Shadow DOM", which is supported in all modern browsers (approximately >95% of users covered).
<div id="menutech-container"></div>
<script>
document.addEventListener("DOMContentLoaded", function() {
let mtUrl = 'ENTER YOUR MENU URL HERE';
fetch(mtUrl + '&embed=true')
.then(response => response.text())
.then(data => {
let container = document.getElementById('menutech-container');
let shadow = container.attachShadow({mode: 'open'});
let wrapper = document.createElement('div');
wrapper.innerHTML = data;
while (wrapper.firstChild) {
shadow.appendChild(wrapper.firstChild);
}
})
.catch((error) => {
console.error('Error:', error);
});
});
</script>
✏️ Make sure to replace ENTER YOUR MENU URL HERE with the URL of your Menutech Digital Menu.
ℹ To load the menu immediately, add the <script>...</script> element in your HTML header.
⚠️ The API-based embed does not include header and collapsible footer.
Adding a loading animation
To add a loading animation to an API-based embed, as the content is being fetched, replace your <div id="menutech-container"></div> element with the following:
<div id="menutech-container">
<style>
.skeleton-screen {
background-color: #fff;
max-width: 996px;
margin: 0 auto;
padding: 30px;
}
.skeleton-screen .skeleton-item * {
border-radius: 5px;
overflow: hidden;
}
.skeleton-screen .skeleton-title {
height: 50px;
width: 50%;
margin-bottom: 20px;
}
.skeleton-screen .skeleton-subtitle {
height: 30px;
width: 20%;
margin-bottom: 60px;
}
.skeleton-screen .skeleton-title,
.skeleton-screen .skeleton-subtitle,
.skeleton-screen .skeleton-name,
.skeleton-screen .skeleton-description {
height: 20px;
}
.skeleton-screen .skeleton-name {
flex-grow: 1;
}
.skeleton-screen .skeleton-description {
flex-grow: 0;
flex-basis: 120px;
}
.skeleton-screen .skeleton-item:not(.pagetop) {
width: 100%;
margin: 30px 0;
display: flex;
gap: 30%;
}
.skeleton-screen > .skeleton-item:nth-child(3) {
gap: 40%;
}
.skeleton-screen > .skeleton-item:nth-child(4) {
gap: 20%;
}
.skeleton-screen > .skeleton-item:nth-child(5) {
gap: 50%;
}
@keyframes shimmer {
0% {
background-position: -200px 0;
}
100% {
background-position: 400px 0;
}
}
.skeleton-screen .skeleton-item * {
animation-duration: 1.5s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: shimmer;
animation-timing-function: linear;
background: #f6f7f8;
background: linear-gradient(
to right,
#eeeeee 8%,
#dddddd 18%,
#eeeeee 33%
);
background-size: 800px 104px;
position: relative;
}
</style>
<div class="skeleton-screen">
<div class="skeleton-item pagetop">
<div class="skeleton-title"></div>
</div>
<div class="skeleton-item pagetop">
<div class="skeleton-subtitle"></div>
</div>
<div class="skeleton-item">
<div class="skeleton-name"></div>
<div class="skeleton-description"></div>
</div>
<div class="skeleton-item">
<div class="skeleton-name"></div>
<div class="skeleton-description"></div>
</div>
<div class="skeleton-item">
<div class="skeleton-name"></div>
<div class="skeleton-description"></div>
</div>
<div class="skeleton-item">
<div class="skeleton-name"></div>
<div class="skeleton-description"></div>
</div>
</div>
</div>
API-based embeds with magnifiable images
Standard embed:
<div id="menutech-container"></div>
<script>
let mtUrl = "ENTER YOUR MENU URL HERE";
document.addEventListener("DOMContentLoaded", function () {
fetch(mtUrl + "&embed=true")
.then((response) => response.text())
.then((data) => {
let parser = new DOMParser();
let doc = parser.parseFromString(data, "text/html");
let container = document.getElementById("menutech-container");
let shadowRoot = container.attachShadow({ mode: "open" });
let externalScripts = [];
let inlineScripts = [];
Array.from(doc.getElementsByTagName("script")).forEach((oldScript) => {
let scriptTag = document.createElement("script");
if (oldScript.src) {
scriptTag.src = oldScript.src;
externalScripts.push(scriptTag);
} else {
scriptTag.textContent = oldScript.textContent;
inlineScripts.push(scriptTag);
}
});
Array.from(doc.body.childNodes).forEach((node) => {
if (node.nodeName !== "SCRIPT") {
shadowRoot.appendChild(node.cloneNode(true));
}
});
let scriptLoadPromises = externalScripts.map((script) => {
return new Promise((resolve, reject) => {
script.onload = resolve;
script.onerror = reject;
shadowRoot.appendChild(script);
});
});
Promise.all(scriptLoadPromises)
.then(() => {
inlineScripts.forEach((script) => {
shadowRoot.appendChild(script);
});
})
.catch((error) => {
console.error("Error loading scripts:", error);
});
})
.catch((error) => {
console.error("Error:", error);
});
});
</script>
Insulated embed:
<div id="menutech-container"></div>
<script>
let mtUrl = "ENTER YOUR MENU URL HERE";
document.addEventListener("DOMContentLoaded", function () {
fetch(mtUrl + "&embed=true")
.then((response) => response.text())
.then((data) => {
let parser = new DOMParser();
let doc = parser.parseFromString(data, "text/html");
let container = document.getElementById("menutech-container");
let shadowRoot = container.attachShadow({ mode: "open" });
let externalScripts = [];
let inlineScripts = [];
Array.from(doc.getElementsByTagName("script")).forEach((oldScript) => {
let scriptTag = document.createElement("script");
if (oldScript.src) {
scriptTag.src = oldScript.src;
externalScripts.push(scriptTag);
} else {
scriptTag.textContent = oldScript.textContent;
inlineScripts.push(scriptTag);
}
});
Array.from(doc.body.childNodes).forEach((node) => {
if (node.nodeName !== "SCRIPT") {
shadowRoot.appendChild(node.cloneNode(true));
}
});
let scriptLoadPromises = externalScripts.map((script) => {
return new Promise((resolve, reject) => {
script.onload = resolve;
script.onerror = reject;
shadowRoot.appendChild(script);
});
});
Promise.all(scriptLoadPromises)
.then(() => {
inlineScripts.forEach((script) => {
shadowRoot.appendChild(script);
});
})
.catch((error) => {
console.error("Error loading scripts:", error);
});
})
.catch((error) => {
console.error("Error:", error);
});
});
</script>