Skip to content

feat: Support setting <html> in _app template#1617

Merged
marvinhagemeister merged 3 commits into
mainfrom
app-html
Aug 11, 2023
Merged

feat: Support setting <html> in _app template#1617
marvinhagemeister merged 3 commits into
mainfrom
app-html

Conversation

@marvinhagemeister

@marvinhagemeister marvinhagemeister commented Aug 10, 2023

Copy link
Copy Markdown
Contributor

This PR allows us to create the <html>-tag ourselves in _app.tsx. In case we didn't render any <html> tag we fall back to the current way of adding an internal outer template. This allows you to set the lang attribute on <html> without having to go through various abstractions, etc.

import { AppProps } from "$fresh/server.ts";

export default function App({ Component }: AppProps) {
  return (
    <html lang="de">
      <head>
        ...
      </head>
      <body>
        <Component />
      </body>
    </html>
  );
}

I tried various approaches to achieve this like adding a marker and replacing that in the HTML string. That proved to be bad for security as the marker could be injected by users. So I landed on the approach in this PR where we essentially swap out user supplied <html>, <head> and <body> tags with an invisible Fragment. We store the props of the old vnode and after the body has rendered we'll render our internal outer template with the user supplied values. Basically this works close to how it worked before.

Fixes #1529, fixes #1595

@bartlomieju bartlomieju left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From an initial review this looks good to me, but I must admit I'm not so knowledgable about this part. I would appreciate another pair of eyes for an approval.

Comment thread src/server/render.ts
SLOTS_TRACKER.clear();

// Clear rendering state
RENDERING_USER_TEMPLATE = false;

@fdemir fdemir Aug 11, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RENDERING_USER_TEMPLATE should not be defined as screaming snake case. it confuses the reader, sounds constant.

@marvinhagemeister marvinhagemeister Aug 11, 2023

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in uppercase to signal that it's a global variable in the context of the module and not a local one. I can rename it though. I'm not attached to the name

@marvinhagemeister

Copy link
Copy Markdown
Contributor Author

Merging, as I got verbal approval internally.

@marvinhagemeister marvinhagemeister merged commit 86f9211 into main Aug 11, 2023
@marvinhagemeister marvinhagemeister deleted the app-html branch August 11, 2023 16:40
@lino-levan

Copy link
Copy Markdown
Contributor

Looks great. Excited to be moving in the right direction!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Setting attributes on <html> element Allow head + body creation in _app.tsx

4 participants