-
Notifications
You must be signed in to change notification settings - Fork 47.1k
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
Allow html conditional comments and doctype #1035
Comments
After checking further, it did seem to break on the doctype (!) as well. |
JSX is not HTML. You'll want to look at the HTML to JSX compiler. http://facebook.github.io/react/html-jsx.html You won't be able to generate doctypes or conditional comments with React. This is technically impossible by design. If you want functionality like this, you might consider creating a script or addon to html-jsx to generate a javascript (JSX) equivalent. |
While this is true it sucks for people who want to do full-page server rendering. I think if we claim to support full-page server rendering we should at least support doctype. |
I can see a good reason for leaving out these portions of the HTML spec. I ended up adding on to this branch of react-app-middleware some changes to allow pulling in a static HTML template initially and then rendering components results into it. See an example of it being used in this repo (see server.js). |
@petehunt I agree with you but I also think it's not really that practical to render full pages inside of react. |
I think a good reason against is that React is used by many as a client side library, and therefore should be kept as light as possible. Perhaps there could be an extension made that implements the "rest" of the HTML5 spec, but could be mixed in only on the server side as client's shouldn't need to render stuff like doctype once the server has. |
I guess you could use React.DOM.injection and modify the JSX transform to read <!doctype. |
@natew |
I have images working like this: I have played with the html to jsx transformer thats on React's site currently, but haven't needed it yet personally. Is there a document that outlines all the supported tags? I haven't checked, but I also haven't gotten too deep into things yet. Edit: As for the self-closing, yea I've always felt more accustomed to using them anyway. |
On second thought, I think I may have missed the point above. Adding something like I don't think there's a document for it (@Daniel15 ) html-jsx transformer does things like turn class -> className and style strings into objects and turn void tags ( |
I too would like to see JSX support HTML conditional comments and not do the things @jhiswin described. I was going to implement a JSX preprendering tool until I found out I couldn't even write HTML comments and doctype... |
I'm not sure if html comments are a deal breaking use case -- are conditional comments the only solution to these problems? -- and doctype can be prepended by your web server request handler or static build system. |
Prepending doctype is easy, conditional comments are harder to because that's the easiest way to conditionally load IE shims, short of this option I'll have to write a bunch of JS pre-shims for browser detection or fiddle with the webserver config, which I may not always have access to. IE8 users are still ~25% of the market. Is it difficult to elevate HTML comments to have same status as JS comments in your Esprima fork? |
@wyuenho As another take on it, you could have a preprocessor (like html-jsx-lib) turn <!x to <_x (or something like ConditionalComment) and then add React.DOM._x My view on it is that you will need a preprocessor to deal with differences between HTML and JSX anyways. |
@jhiswin Or better yet, preprocess to JSX. As a hack it'll work, just have to make sure to spit out the right string what |
I still think it's best to have JSX support as many HTML5 constructs as possible. Just fewer surprises. |
BTW: rendering on the server doesn't necessarily mean that we need to be able to render full pages, especially since browser support for updating We could probably get comments into core with a little work (mostly just cloning ReactTextComponent to work with comments and figuring out how to look it up by ID), not sure about the jsx transform. Not sure if we can prioritize this relative to other things (especially since this can be worked around), but I think a PR would definitely be considered. |
Will look into it this weekend. What's the release schedule for 0.9? |
Sometime between Tuesday and Friday |
No rush then :) |
Comments will be interesting because the typical setup is to have a number of them all in a row, without a closing tag. Not sure the syntax or tricks you'd have to do to build a root level component that has all the opening tags in conditionals. |
Just a heads-up, there are a bunch of bugs with comments in IE8 in particular I think, where they get merged or get lost IIRC. Shouldn't be a problem for server-rendering, but it may mess up client-side |
Has there been any further progress on bringing doctypes into React? |
@balanceiskey React can't mount higher than |
@syranide Prepending doctype just feels a touch hacky. That said, you're right, it's probably not a huge issue. |
I think React's rendering model needs to be separate from the DOM. There are React components for the html, body and iframe tags, so the idea of the DOM being separate is a good one, IMHO. Prime use case is iFrames as a component, which has a DOM itself and therefore INCLUDES doctype, HTML, HEAD, BODY and other top-level tags, so I think if iframe is actually officially being supported as a component then it's fundamental to support these other components. |
Should I not be using React to render complete documents before serving? |
@adjavaherian You shouldn't need to. |
For my usecase, I use React to render emails using |
In React 0.14, rendering the |
@zackify That's unrelated, please file a new issue with steps to repro |
Any update on this? |
No update. |
I've just ran into this. The ability to render full page with just react can help to deal with SEO, title and many other things with much flexibility. And you won't even need something like helmet or react-document-title. And it simply seems logical to me to handle whole application state within react. While prepending doctype is easy, other things are really hard or impossible sigh. |
Well, I found out that some people say that changing head with virtual DOM can push some browsers to go crazy, which is definitely worse than not having whole app within react. Maybe, it wasn't a good idea after all... |
@baygeldin Specifically, can you define "go crazy"? Which browsers, changing which nodes? |
@jimfb I guess I should have said "an unexpected behavior". I couldn't find a good example, but from what I understood the main arguments are: 1) Browsers do not expect replacing the whole nodes in the head, so their behavior is not standardized 2) It's a common practice for browser-extensions to inject external resources to the head, react will override those if it handles the head tag. Also, according to MDN, document.head is read-only. Sorry, I don't have concrete examples and time to investigate it :( I decided to go the standard way of doing things. |
+1 for this. It's quite a bit unexpected that server-side react can't actually render the whole page. |
Hi! I have found a new method to include HTML comments (e.g. conditional IE comments) in JSX and React components using a Web Component. https://github.com/optimalisatie/react-jsx-html-comments <react-comment>[if lt IE 8]</react-comment>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<react-comment>[endif]</react-comment> |
Hello, I added additional component Head in my server-side to resolve this situation:
and now I can just use it:
Maybe this is not perfect solution and requires some additional code. Please, review and say what do you think about it. Thanks. |
@sumbad The children can contain an array, this requires a separate check, because ReactDOMServer.renderToStaticMarkup can not render arrays. |
This is definitely something needed for server side rendering. For right now we have to inject it after we call |
+1 |
Closing as there is an easy workaround (string manipulation before sending the markup for doctype, and Adding support for comments or doctype would have to span multiple projects (React, Babel, ESLint, etc) and yields little benefit, so it is unlikely we’ll be working on this. |
For everyone still finding this issue and wondering just how to use TL;DR: renderHead() {
return (
var comment = '<!--[if lte IE 9]><script src="/public/media.match.js"></script><![endif]-->';
<head>
<title>Website title</title>
<meta name="react-comment-hack"
dangerouslySetInnerHTML={{__html: comment}}>
</meta>
</head>
);
} |
still error
|
i'm useing this to fix it |
@sumbad stumbled across this and years later it looks like you're on the right path. Your solution didn't work with Context, so here's an updated solution that does that and adds some generic helpers in the same approach as import React, { useContext } from "react";
import ReactDOMServer from "react-dom/server";
export function RawHTMLWrapper({
as,
children = [],
contexts = [],
renderer = ReactDOMServer.renderToStaticMarkup,
createElement = React.createElement,
...rest
}) {
const values = contexts.map((c) => useContext(c));
const toHtml = (value) => {
if (typeof value !== "string") {
const element = contexts.reduce((el, c, idx) => {
return <c.Provider value={values[idx]}>{el}</c.Provider>;
}, value);
return renderer(element);
} else {
return value;
}
};
let dangerousInnerHTML;
if (Array.isArray(children)) {
dangerousInnerHTML = children.map(toHtml).join("");
} else {
dangerousInnerHTML = toHtml(children);
}
const props = {
...rest,
dangerouslySetInnerHTML: { __html: dangerousInnerHTML }
};
return createElement(as, props);
}
const elements = [
"div",
"tr",
"table",
"tbody",
"td",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"head",
"body",
"html",
"img",
"span",
"a",
"button",
"ul",
"ol",
"li"
];
const reducer = (acc, el) => {
const Componet = ({ children, contexts, ...rest }) => (
<RawHTMLWrapper as={el} contexts={contexts} {...rest}>
{children}
</RawHTMLWrapper>
);
return { ...acc, [el]: Componet };
};
export const raw = elements.reduce(reducer, {});
export function Raw(contexts) {
const reducer = (acc, el) => {
const Componet = ({ children, ...rest }) => (
<RawHTMLWrapper as={el} contexts={contexts} {...rest}>
{children}
</RawHTMLWrapper>
);
return { ...acc, [el]: Componet };
};
return elements.reduce(reducer, {});
} And then using it via <FooContext.Provider value="nested context">
<h1>raw-components</h1>
<div>
Useful for rendering custom HTML content (e.g. comments). Inspired by
styled components.
</div>
<raw.ul contexts={[FooContext]}>
<li>Escapes nested {`<html>`}</li>
<raw.li>Doesn't escape in {`<b>raw</b>`} components</raw.li>
<raw.li>
{`<!-- Before some comments -->`}
Supports HTML comments (inspect source here)
{`<!-- After some comments -->`}
</raw.li>
<raw.li
style={{ color: "red" }}
title="and supports titles"
className="boldone"
>
Supports style props (etc.)
</raw.li>
<li>
Supports <Consumes />
</li>
{`<li>Supports bad HTML (e.g. no closing tags, thanks browsers!)`}
</raw.ul>
</FooContext.Provider> You can see it running here: https://codesandbox.io/s/react-raw-html-wrapper-hc2jq?file=/src/RawHTMLWrapper.js:91-674 |
I'm hacking on an fully server and client compatible app using React. One obstactle I'm running into is it seems react doesn't like exclamation marks in your jsx-style code.
Here's an example of a pretty standard boilerplate for HTML:
I think it's getting stuck on the conditional comments in this example.
I would prefer to keep this code in the HTML style, and to render it from the server without making major changes, it needs to be inside a react class. I'd be open to trying to hack this together, I may take a stab sometime this coming week.
The text was updated successfully, but these errors were encountered: