Skip to content
This repository has been archived by the owner on Apr 8, 2020. It is now read-only.

Angular 2.4.5 template nested html/head/body duplicates #662

Closed
Xeevis opened this issue Feb 9, 2017 · 11 comments
Closed

Angular 2.4.5 template nested html/head/body duplicates #662

Xeevis opened this issue Feb 9, 2017 · 11 comments

Comments

@Xeevis
Copy link

Xeevis commented Feb 9, 2017

I'm not sure if it's an issue, but when I look at static source of the page that gets prerendered on server I see structure like this

<html>
    <head>
        <title></title>
    </head>
    <body>
        <app>
            <html>
                <head>
                    <title></title>
                </head>
                <body>
                    <app></app>
                </body>
            </html>
        </app>
        <script>
    </body>
</html>

Which seems odd. Could it be bug?

@SteveSandersonMS
Copy link
Member

That doesn't happen when I try it (with the current template and Angular 2.4.7). I get a structure like the following:

html
    body
        app
            title
            app

There's no nested html or body. There is a nested app element, which is irritating but not really a major problem. This is a limitation of Angular Universal (it doesn't completely respect the document template you supply to it, if it's only a document fragment and not a complete HTML page). If it bothers you, you can replace the outer app element in your cshtml with a div or similar (the only drawback to doing so is that then you must leave server-side rendering enabled, or you'd have to change it back to an app element manually).

If you can provide repro instructions for getting the nested html document, please let us know.

@Xeevis
Copy link
Author

Xeevis commented Feb 10, 2017

I'm not doing anything special just

  1. yo aspnetcore-spa [0.8.4] > Angular 2.4.5 (Experimental) > No > Angular2Spa
  2. dotnet run

Make sure you are looking at the static source of the page (CTRL + U), browser's Developer Tools won't show it, maybe because it's invalid html?

image

@hheexx
Copy link

hheexx commented Feb 12, 2017

@SteveSandersonMS
Copy link
Member

Ah yes, I see what you mean.

Currently this is a limitation of Angular's server-side rendering (it only understands the idea of returning a complete HTML page, not a document fragment). It's also a regression - they used to handle this better until recently.

If avoiding the oddly-shaped document matters to you (and I agree it should) then please tell the Angular Universal people that you want it to support returning document fragments. I'd suggest posting to angular/angular#13822

@hheexx
Copy link

hheexx commented Feb 21, 2017

@SteveSandersonMS
Does the fact that you linked to that thread means this will not work even with angular4 or you don't know?

It is kind of big deal. SEO is primary use case for Universal and we are not sure how Google would treat html like this.

@SteveSandersonMS
Copy link
Member

@hheexx I haven't yet heard the Angular team confirm for sure whether they are going to put back the support for returning document fragments in Angular 4. Again, if this is important to you (and I know it is to many people), then please lobby the Angular folks about it directly.

@hheexx
Copy link

hheexx commented Feb 21, 2017

Here is hacky code that fixes this:
return requestZone.run<Promise<string>>(() => platform.serializeModule(AppModule)).then(html => { resolve({ html: html.slice(27, html.length - 14).replace('</head><body>', '') }); }, reject);

Also in index.cshtml I advice changing app to div because we already have app tag returned from Universal.

<div asp-prerender-module="ClientApp/dist/main-server">Loading...</div>

@derricksimpson
Copy link

:) very interesting hack. But hey, it works. :)

b.t.w. Couldn't one use @SteveSandersonMS sample code here #607 to prevent any markup from being written out from the C# side of things, then move all the js/css includes into the primary app.component.html and use only the output from Angular Universal?

@MarkPieszak
Copy link
Contributor

The goal is to have code setup like in #607 (since otherwise we don't get to set any of the SEO must-have's like Title / Meta tags). I'm working on getting all of that going right now, hopefully have it up and running so we can test out a few scenarios.
@derricksimpson @SteveSandersonMS @hheexx

@MarkPieszak
Copy link
Contributor

So far I got them successfully integrated and server-rendering 😸
I need to do some more testing to make sure everything is working, we're still in beta with Angular 4.0 at the moment, but I'm working on cleaning up retrieving Title/Meta & style data right now.

image

@derricksimpson @SteveSandersonMS @hheexx

@salarcode
Copy link

salarcode commented Feb 15, 2018

In addition to @hheexx answer, here is the hacky code for angular 5 in asp.net core,

in boot.server.ts file change the code to this:

resolve({
html: (() => {
	let apphtml = state.renderToString();
	apphtml = apphtml.replace('<html><head><style>', '<style>').replace('</head><body><app', '<app').replace('</app></body></html>', '</app>');
	return apphtml;
})()});

and don't use <app change it to div
<div asp-prerender-module="ClientApp/dist/main-server">Loading...</div>

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants