-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add possibility to provide a external preview renderer endpoint #65
Comments
In our Slack channel, a developer came up with the following solution in his project. I have not tested this because I do not have the usecase, but maybe this will help somebody else 🙂 <iframe
style="position:fixed; top:0; left:0; bottom:0; right:0; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;"
id='__NUXT__'
src="//{{ frontend_url }}{{ content.url }}?preview=true"></iframe>
<script>
var frame = document.getElementById('__NUXT__')
frame.onload = function(){
frame.contentWindow.postMessage({{ jsonData|raw }}, '*')
}
</script> |
On The frontend side you can add this one to get the content :) if ((this as any).$route.query.preview) {
window.addEventListener(
'message',
(event) => {
if (event.data) {
;(this as any).$store.dispatch('content/preview', {
content: event.data.content,
view: event.data.view,
})
}
},
false
)
}
}, |
Full Example can look like the following: Adding the following to all your templates: <view>pages/headless</view> Then create this template which will include the iframe: <!doctype html>
<html lang="{{ app.request.locale }}">
<head>
<title>Preview</title>
<style>
body {
margin: 0;
}
#application-frame {
border: 0;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
</style>
</head>
<body>
{% if app.request.attributes.get('preview') %}
<iframe id="application-frame" src="http://127.0.0.1:8089/test.html"></iframe>
{% endif %}
{% block content %}
{% if app.request.attributes.get('preview') %}
<script>
var frame = document.getElementById('application-frame');
frame.onload = function() {
frame.contentWindow.postMessage({{ headless|json_encode|raw }}, '*'); // TODO * should be replaced by correct origin
}
</script>
{% endif %}
{% endblock %}
</body>
</html> The app side could look like this <!doctype html>
<html lang="en">
<head>
<title>Test</title>
<style>body { background: red; }</style>
</head>
<body>
<pre id="content">
Waiting for data ...
</pre>
<script>
window.addEventListener(
'message',
function(event) {
// TODO this should be checked to avoid unsecure data being send from other origin
// if (event.origin !== 'https://expected-origin-address') {
// return;
// }
if (event.data) {
document.getElementById('content').innerText = JSON.stringify(event.data, null, 4);
}
},
false
)
</script>
</body>
</html> |
The solution with the iframe and postMessage feels from my side good. We still would need the possibility to configure an URL (iframe) so there are for me 2 open points for this issue. 1. Where to configure the url and how to handle multi webspace support Simple configuration: sulu_headless:
preview_url: '%env(PREVIEW_ENDPONT)%' Multi Webspace endpoint: sulu_headless:
preview_url:
webspace_a: '%env(PREVIEW_WEBSPACE_A_ENDPONT)%'
webspace_b: '%env(PREVIEW_WEBSPACE_B_ENDPONT)%' With some symfony config magic this given config can be detected and correctly converted into the array of available webspaces. So we just need a twig extension to get the preview url e.g.: {% set previewUrl = sulu_headless_preview_url(request.webspace) %} 2. Security for the postMessage The postMessage has a security included that only postMessage can be receive which targetOrigin does match. As mention in the documentation about postMessage: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage this should always be used to avoid sending data to maybe an external website which should not happen. |
Thank you for your response and efforts. I apologize for any inconvenience caused. I have created a page called default-url. Here are the results I get when testing the following URLs: When I access: When I access: The issue seems to be related to adding .json to the path, and I would like to resolve this problem. Do you have any ideas or solutions for this issue? I appreciate your help in advance. Here is my current configuration: |
Means you did not use the If you use the Headless Controller you should get into that controller and get a JSON responded:
Your app should never access a route without
This routes has nothing todo with providing Content Pages Headless. The The |
I installed the SuluHeadlessBundle using this command: I added this line to my configuration: It looks like enabling the bundle and adding its routes is done automatically during installation. Then, I created a page in the admin and added an XML file for it. When I open: But when I try: I followed all the steps in the SuluHeadlessBundle docs here: Any idea what I might be missing? Thanks! |
good job @MarnissiDev |
When you are using nextJS or something similar the preview HTML need also be rendered by the nextJS server. This could be implemented in the Headless Controller the following way.
The text was updated successfully, but these errors were encountered: