WebReflection / heresy-ssr

🔥 heresy 🔥 Server Side Rendering
ISC License
88 stars 1 forks source link

Dynamic title #23

Closed CaptainJKoB closed 3 years ago

CaptainJKoB commented 3 years ago

Hello,

When rendering a dynamic title for the site heresy-ssr appends the anchor comment <!---0.368698%-->, which is later displayed in the title bar of the page.

Example:

import { document, render, html } from 'heresy-ssr';

const title = 'My awesome title';

render(document, html`
  <html>
    <head>
      <title>${ title }</title>
    </head>
    <body>
      <div>Hello</div>
    </body>
  </html>
`);

I found a workaround using the ref method but I am not really sure if it is the best solution.

import { document, render, html } from 'heresy-ssr';

const title = 'My awesome title';

render(document, html`
  <html>
    <head>
      <title ref="${ elm => elm.textContent = title }" />
    </head>
    <body>
      <div>Hello</div>
    </body>
  </html>
`);

Is this behaviour for the title element right?

Thank you.

WebReflection commented 3 years ago

All interpolations use comments by design, but as these comments are always the same, and you should serve gzipped/compressed content, this should never be an issue for you.

Your workaround is OK, but also unnecessary.

TL;DR: this is how every template literal engine works (via comments used as pins for updates) and heresy uses lighterhtml, so this won't change and this is not a real-world issue.

Hope this answered your question.

WebReflection commented 3 years ago

P.S. if you don't use heresy features and all you want is to use template literals to safely render SSR, try uhtml-ssr or ucontent out instead, these are SSR only and won't place comments in the page.

CaptainJKoB commented 3 years ago

I use heresy features, I just wanted to show a reproducible example. My problem isn't really the size/compression of the content, but the final output that is interpreted by the browser. I understand the usage of comments in template engines, but in this particular instance I don't think it's working as intended.

Currently for the first example above, heresy-ssr output for the <title> element is:

  <title>My awesome title<!---0.368698%--></title>

The specification states that any content within the <title> is interpreted as text. So the title browsers are going to display is My awesome title<!---0.368698%-->. The comment is not ignored. This could cause some SEO problems, but the workaround in the second example seems to fix this issue.

WebReflection commented 3 years ago

The specification states that any content within the is interpreted as text.</p> </blockquote> <p>OK, this is a bummer, yes, but your workaround, if meant for title only, is the way I'd go too.</p> <p>Herey uses basicHTML which is DOM after all, it's not a text parser, it's like a browser in NodeJS.</p> <p>Being based on lighterhtml, I can't change this, but what I could do, is erase comments from <code><title>...</title></code> only, whenever the output is rendered (via the <code>toString()</code>) ... would that work for you?</p> <p>Alternatively I can put this in the README, as it's a weird W3C caveat I wasn't aware myself, so apologies for closing this prematurely.</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/CaptainJKoB"><img src="https://avatars.githubusercontent.com/u/11009044?v=4" />CaptainJKoB</a> commented <strong> 3 years ago</strong> </div> <div class="markdown-body"> <p>No harm done. Rendering using <code>toString()</code> seems as an acceptable solution for the <code><title></code> element. Using the workaround just for this instance seems kinda more as a hack to me.</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/WebReflection"><img src="https://avatars.githubusercontent.com/u/85749?v=4" />WebReflection</a> commented <strong> 3 years ago</strong> </div> <div class="markdown-body"> <blockquote> <p>Being based on lighterhtml, I can't change this</p> </blockquote> <p>I lied ... there are special cases for uhtml/lighterhtml such as textarea and style, and I think title, together with script, xmp, and plaintext, should be added to the list of exception.</p> <p>Will test around, and fix this properly.</p> <p>Thanks for the bug though 👋</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/WebReflection"><img src="https://avatars.githubusercontent.com/u/85749?v=4" />WebReflection</a> commented <strong> 3 years ago</strong> </div> <div class="markdown-body"> <p>This should have been fixed, together with other weird cases:</p> <ul> <li>script</li> <li>style</li> <li>plaintext</li> <li>textarea</li> <li>xmp 👋</li> </ul> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/CaptainJKoB"><img src="https://avatars.githubusercontent.com/u/11009044?v=4" />CaptainJKoB</a> commented <strong> 3 years ago</strong> </div> <div class="markdown-body"> <p>Tested, works like a charm 👍 Thanks, great work.</p> </div> </div> <div class="page-bar-simple"> </div> <div class="footer"> <ul class="body"> <li>© <script> document.write(new Date().getFullYear()) </script> Githubissues.</li> <li>Githubissues is a development platform for aggregating issues.</li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script> <script src="/githubissues/assets/js.js"></script> <script src="/githubissues/assets/markdown.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/highlight.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/languages/go.min.js"></script> <script> hljs.highlightAll(); </script> </body> </html>