Skip to content
This repository was archived by the owner on Nov 22, 2024. It is now read-only.
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

Closed

Description

@SteveSandersonMS

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.

For example, instead of this:

ngUniversal.bootloader({
    ...,
    template: '<!DOCTYPE html>\n<html><head></head><body><app></app></body></html>'
})

... it should be possible to do this:

ngUniversal.bootloader({
    ...,
    template: '<app></app>'
})

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.

Activity

  1. self-assigned this
    on Apr 5, 2016
  2. MarkPieszak commented on Apr 6, 2016

    @MarkPieszak
    Contributor

    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?

  3. jeffwhelpley commented on May 6, 2016

    @jeffwhelpley
    Contributor

    @gdi2290 We should have this as a high priority. What is involved in this change?

  4. MarkPieszak commented on May 10, 2016

    @MarkPieszak
    Contributor

    @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>

  5. SteveSandersonMS commented on May 17, 2016

    @SteveSandersonMS
    Author

    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 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.

  6. PatrickJS commented on May 17, 2016

    @PatrickJS
    Contributor

    I'm working on this today after Jsonp support

  7. MarkPieszak commented on May 18, 2016

    @MarkPieszak
    Contributor

    @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!

  8. jeffwhelpley commented on Oct 3, 2016

    @jeffwhelpley
    Contributor

    @gdi2290 what is the status here? we currently don't have the ability to do the html component, right?

  9. MarkPieszak commented on Oct 4, 2016

    @MarkPieszak
    Contributor

    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.

  10. jeffwhelpley commented on Oct 4, 2016

    @jeffwhelpley
    Contributor

    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.

  11. MarkPieszak commented on Oct 4, 2016

    @MarkPieszak
    Contributor

    Sounds good to me, yea there's definitely a lot of high priority stuff right now.

  12. SteveSandersonMS commented on Oct 31, 2016

    @SteveSandersonMS
    Author

    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?

  13. MarkPieszak commented on Oct 31, 2016

    @MarkPieszak
    Contributor

    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);
      }
    
  14. PatrickJS commented on Oct 31, 2016

    @PatrickJS
    Contributor

    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.

  15. PatrickJS commented on Jan 8, 2017

    @PatrickJS
    Contributor

    might be supported in ng4
    angular/angular#13822

  16. angular-automatic-lock-bot commented on Sep 4, 2019

    @angular-automatic-lock-bot

    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.

  17. locked and limited conversation to collaborators on Sep 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions