You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 22, 2024. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 22, 2024. It is now read-only.
Support rendering just a single component rather than a complete HTML document #347
As discussed, please add support for rendering just a single component element to an HTML string, instead of requiring the template to be an entire HTML document.
Currently, Angular Universal automatically wraps the output in <html> etc even if it wasn't requested in the template. This feature is particuarly relevent when including Angular 2 server-side rendered content in an existing server-rendered page, e.g., on ASP.NET.
The ASP.NET templates don't point to any initial HTML page in the sense that I think you mean. We're not using the angular2-universal view engine or any equivalent. We are using angular-universal just to render-as-string individual Angular 2 components that get injected into a page being generated by ASP.NET.
You'll see below the TODO comment there about this issue what markup we currently have to pass to angular2-universal as a workaround. We just need angular2-universal not to assume it's working on an entire HTML document, and to be happy working on an arbitrary document fragment.
I'm also wondering how we can get to work (and inject CSS) if we have no supplied tags in the
Could the serializeApplication method return both html and css strings (currently it just returns an html string)? We can take care of injecting them into the right parts of the page.
@gdi2290 I'm not sure if you saw my message on the Slack a while back, but to me, it looked like using parseFragment helped not create the entire <html> tree. Not sure if that would help you at all!
Originally it worked when I just looked to see if there was doc type, an html tag etc (then proceed like normal), otherwise do parseFragment on the or whatever was passed in and it did seem to work. @jeffwhelpley think the codes still there, just commented out.
It looks to me like this is now fixed. At least, there's no longer any error when prerendering just a template containing <app></app>, rather than an entire <html>...</html> doc.
Could you confirm whether this is now officially supported? It's not going to break anything subtle in angular-universal if people start just passing <app></app> as the template?
Hey @SteveSandersonMS we updated to parse5 2.* a while back, which now returns a ASTNode.Document, so that might be why it isn't erroring out anymore. The problem is now the page will have 2 <html><head><body> tags since it's going to return those back for you. When you view source you'll be able to see them inside your original <app> tag you passed.
I just tested it out, and it does work, but we still want to be using parseFragment in this situation.
Also, I tried adding in my original logic on our side, and it worked in running parseFragment (since in your case <html> </html> isn't found in the document string. @gdi2290 Is this adequate enough of a test for this situation?
I'll create a PR #614 about it so we can get this one ironed out.
// Build entire doc <!doctype><html> etc
if (documentHtml.indexOf('<html>') > -1 && documentHtml.indexOf('</html>') > -1) {
doc = parse5.parse(documentHtml, { treeAdapter : parse5.treeAdapters.htmlparser2 });
} else {
// ASP.NET case : parse only the fragment - don't build entire <html> doc
doc = parseFragment(documentHtml);
}
this will still be an issue without replacing all of the platform services being created in core such as Meta Service (in PR angular/angular#12322), Title Service (already in), ignore Base element, ResourceLoader, and replace Style Host to not use an element.
Angular core wants to be agnostic to the platform which means everything should live within the app element tag. The problem is that is not that case as there are platform services that are needed to change values outside of that element. Platform services are slowly being built out now that final is released. platform-node needs to provide a way to manage these platform services in the case where there is no full document and then provide a way to grab these global values and return them.
Activity
MarkPieszak commentedon Apr 6, 2016
I could try and take this one if it's not too difficult you think @gdi2290 ?
It sounds like we just need to be testing for the existence of
<!doctype>or<html>etc and not applying it if need be?jeffwhelpley commentedon May 6, 2016
@gdi2290 We should have this as a high priority. What is involved in this change?
MarkPieszak commentedon May 10, 2016
@SteveSandersonMS Hey Steve, the initial html page that you are pointing to for Universal, has no
<html></html><body></body>tags, etc correct?I have a fix for this in the works, trying to look into it more to make sure I cover everything.
I'm also wondering how we can get
<universal-styles />to work (and inject CSS) if we have no supplied tags in the<head>SteveSandersonMS commentedon May 17, 2016
The ASP.NET templates don't point to any initial HTML page in the sense that I think you mean. We're not using the angular2-universal view engine or any equivalent. We are using angular-universal just to render-as-string individual Angular 2 components that get injected into a page being generated by ASP.NET.
You can find an example of the server-side boot code we're using here: https://github.com/aspnet/NodeServices/blob/master/templates/Angular2Spa/ClientApp/boot-server.ts
You'll see below the
TODOcomment there about this issue what markup we currently have to pass to angular2-universal as a workaround. We just need angular2-universal not to assume it's working on an entire HTML document, and to be happy working on an arbitrary document fragment.Could the
serializeApplicationmethod return bothhtmlandcssstrings (currently it just returns anhtmlstring)? We can take care of injecting them into the right parts of the page.PatrickJS commentedon May 17, 2016
I'm working on this today after Jsonp support
MarkPieszak commentedon May 18, 2016
@gdi2290 I'm not sure if you saw my message on the Slack a while back, but to me, it looked like using
parseFragmenthelped not create the entire<html>tree. Not sure if that would help you at all!jeffwhelpley commentedon Oct 3, 2016
@gdi2290 what is the status here? we currently don't have the ability to do the html component, right?
MarkPieszak commentedon Oct 4, 2016
Originally it worked when I just looked to see if there was doc type, an html tag etc (then proceed like normal), otherwise do parseFragment on the or whatever was passed in and it did seem to work. @jeffwhelpley think the codes still there, just commented out.
jeffwhelpley commentedon Oct 4, 2016
OK, so in that case, this issue is dependent on #533 which is a top priority right now. Let's focus on that and then we can come back to this.
MarkPieszak commentedon Oct 4, 2016
Sounds good to me, yea there's definitely a lot of high priority stuff right now.
SteveSandersonMS commentedon Oct 31, 2016
It looks to me like this is now fixed. At least, there's no longer any error when prerendering just a template containing
<app></app>, rather than an entire<html>...</html>doc.Could you confirm whether this is now officially supported? It's not going to break anything subtle in angular-universal if people start just passing
<app></app>as the template?MarkPieszak commentedon Oct 31, 2016
Hey @SteveSandersonMS we updated to parse5 2.* a while back, which now returns a ASTNode.Document, so that might be why it isn't erroring out anymore. The problem is now the page will have 2
<html><head><body>tags since it's going to return those back for you. When you view source you'll be able to see them inside your original<app>tag you passed.I just tested it out, and it does work, but we still want to be using
parseFragmentin this situation.Also, I tried adding in my original logic on our side, and it worked in running parseFragment (since in your case
<html> </html>isn't found in the document string.@gdi2290 Is this adequate enough of a test for this situation?
I'll create a PR #614 about it so we can get this one ironed out.
PatrickJS commentedon Oct 31, 2016
this will still be an issue without replacing all of the platform services being created in core such as Meta Service (in PR angular/angular#12322), Title Service (already in), ignore Base element, ResourceLoader, and replace Style Host to not use an element.
Angular core wants to be agnostic to the platform which means everything should live within the app element tag. The problem is that is not that case as there are platform services that are needed to change values outside of that element. Platform services are slowly being built out now that final is released.
platform-nodeneeds to provide a way to manage these platform services in the case where there is no full document and then provide a way to grab these global values and return them.PatrickJS commentedon Jan 8, 2017
might be supported in ng4
angular/angular#13822
Changed boot-server since issue 347 was fixed in angular universal. a…
angular-automatic-lock-bot commentedon Sep 4, 2019
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.