Skip to content
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

autorender removes <link> tags #41

Open
justinbmeyer opened this issue Jan 12, 2017 · 23 comments
Open

autorender removes <link> tags #41

justinbmeyer opened this issue Jan 12, 2017 · 23 comments
Labels

Comments

@justinbmeyer
Copy link
Contributor

Currently, autorender removes <script>, <link>, and <style> tags that are in the template. This causes bugs when these tags are expected to be part of the page, for example a favicon:

<link rel="icon" type="image/png" href="/favicons/favicon-32x32.png" sizes="32x32">

Why are these removed? What can be done to allow these types of tags? Thanks!

cc @lkodai

@justinbmeyer
Copy link
Contributor Author

justinbmeyer commented Jan 12, 2017

Since creating this issue, I think I understand why it does this -> to prevent a double load of script, link, and style tags if the app has been server-side rendered (SSR).

The app using done-autorender is not using SSR, but it has things like <link rel="icon" type="image/png" href="/favicons/favicon-32x32.png" sizes="32x32"> in its "head".

I see a few options:

1. Have this project only use <body> in index.stache

Presumably, much of what's in index.stache's <head> should be in the page that is being sent back by the server. If people are using done-autorender in non SSR environments, we should probably encourage people to do this.

We could:

  • Detect if we aren't in an SSR environment and if there are script, head, or style tags in the head, we tell people to use the <body>-only version of done-autorender.
    • How can we detect if we are SSR? Special attribute on the SSR-ed HTML?
  • Detect when there is only a <body> or a lack of <body>.

2. Support both served-<head> and autorendered-<head> elements

This could be tricky as the elements might not be the same. We could do a diff and only add what's different. But it feels strange to have a different behavior of the <body> vs the <head>.

3. Detect we aren't doing SSR and do a full replacement of head.

If done-autorender knows it's a pure client-render situation, it should not ignore anything in the head.

My thoughts

We should do #1 + #3.

@matthewp
Copy link
Contributor

matthewp commented Jan 12, 2017

You can put links in the body too, so #1 doesn't solve anything. I think we can do #2. We're only talking about links with an href and scripts here so not a big deal to keep a map of the ones already in the page.

@matthewp matthewp self-assigned this Jan 12, 2017
@justinbmeyer
Copy link
Contributor Author

justinbmeyer commented Jan 12, 2017 via email

@matthewp
Copy link
Contributor

Limiting done-autorender to only the <body> would remove some valid use-cases such as dynamically setting the title:

<head>
  <title>My site | {{page}}</title>
</head>
<body>
 ...
</body>

As far as #3 goes, how would you know that you're in a client-only rendering situation? The only thing I can think is to add some type of attribute to the markup. Maybe something like this:

<html autorender-all>
  ...
</html>

@justinbmeyer
Copy link
Contributor Author

Sorry, to be clear, I'm not suggesting the body-only part of #1, I'm suggesting simply having a warning to tell people they probably should be putting these things in their served page.

Yes for #3 that's exactly what I suggested above:

How can we detect if we are SSR? Special attribute on the SSR-ed HTML?

It would probably be ideal if this was a className ... mostly because it would be easy to style the ssr-ed HTML in a disabled mode.

@matthewp
Copy link
Contributor

In a disabled mode? Can you clarify what you mean there?

@justinbmeyer
Copy link
Contributor Author

I mean the style sheet can make the site look a shade of gray before re-attachment, to give the user a clear signal that the site is un-usable.

.done-ssred {
  color: #808080
}

If we remove that className after re-attachment, then the text color will go to black.

@matthewp
Copy link
Contributor

That makes omitting duplicate links/scripts an opt-in rather than opt-out feature. I don't think it should be opt-in. I don't think anyone ever wants duplicates so they shouldn't have to add a class to prevent them.

@matthewp matthewp added the p1 label Jan 12, 2017
@matthewp
Copy link
Contributor

matthewp commented Jan 12, 2017

After talking about it with @justinbmeyer sort of concluded that there is no good reason to put scripts or links into both the HTML and the Stache files. You would put them in one or the other, in which case there wouldn't be duplicates.

The only scenario for putting it in both is when server rendered. So we're going to have done-autorender add an attribute when being server rendered to the documentElement that gets removed after reattachment.

Some ideas for the attribute:

  • unresolved
  • unattached
  • detached
  • not-live
  • reattaching

I kind of like unattached or detached.

@matthewp
Copy link
Contributor

matthewp commented Jan 13, 2017

Need tests for:

  • - server rendered
    • The attribute should be added.
  • - Reattaching - SSR
    • The attribute should be removed.
    • No duplicates should exist.
  • - Reattaching - No SSR
    • all links/scripts should be copied over.

matthewp added a commit that referenced this issue Jan 17, 2017
This implements a new attribute that is added to the documentElement,
	 *data-detached*. it is added in SSR and removed when attachment is
	 complete on the client.

Because of this new attribute, we will insert any links/styles/scripts
when that attribute doesn't exist.

Fixes #41
@matthewp
Copy link
Contributor

This is in 1.0.0-alpha.3, here's how to use it: https://github.com/donejs/autorender/tree/major#server-rendering

@matthewp
Copy link
Contributor

matthewp commented Jan 19, 2017

The existing solution has a bug where upon rerendering (for live-reload), because the data-detached attribute is gone it will insert scripts even though they are already there. This causes a problem where the Steal script tag is continuously reinserted and the entire app loads over and over and over.

I've reverted the feature since it's such a bad bug temporarily while I fix it.

matthewp added a commit that referenced this issue Jan 19, 2017
This is related to the data-detach feature. During live reload we go
through reattachment again, in which case script/link/style elements are
on the page. We need to make sure not to insert them again.

Closes #41
@matthewp
Copy link
Contributor

I reverted this again. This is really hard to get right 😕 You have to maintain state to know if reattachment has occurred and if so, use the old behavior of not push in scripts. Otherwise if you push in a steal script you'll get cycles as it continuously reinserts steal over and over again.

This feels a little dangerous to me and I'd like to back away from it and rethink it through a bit.

@matthewp matthewp reopened this Jan 19, 2017
@matthewp
Copy link
Contributor

matthewp commented Feb 13, 2017

@chasenlehara why did you put this on the DoneJS 1.0 release? I don't think it should be. As I detailed about, this is really easy to get wrong and getting it wrong is very bad consequences (causing the browser to lock up, for example).

And it serves a pretty niche need (putting links in index.stache but not in your html).

@chasenlehara
Copy link
Member

I put it in the 1.0 release epic because it’s a p1, but we can move it to another release epic or out completely if you don’t think we should address it now or schedule it for a future release. 🙂

@matthewp
Copy link
Contributor

I don't think this should be part of the 1.0 release or that it's a P1.

@matthewp
Copy link
Contributor

To clarify, I've fixed this twice only to find that it caused even worse bugs. Specifically when coupled with live-reload it would cause steal.js to be inserted multiple times which caused infinite recursion (each time steal.js was inserted it would then re-import your entire app including done-autorender which would then insert steal.js which would re-import your entire app, etc).

This can be fixed but given it is highly stately thing I'd want to refactor all of done-autorender to make sure that this feature could be isolated and properly tested for all scenarios. done-autorender's code is already not the best, so I wouldn't want to shove this feature in in a way that isn't readable.

@matthewp matthewp removed their assignment Mar 21, 2017
@pYr0x
Copy link

pYr0x commented Sep 13, 2017

@matthewp is this issue solved with the current 1.3 release?

@matthewp
Copy link
Contributor

Nope

@pYr0x
Copy link

pYr0x commented Sep 14, 2017

so what is the current workaround?

@matthewp
Copy link
Contributor

Put the link tags into your stache file, I think.

@pYr0x
Copy link

pYr0x commented Sep 20, 2017

as justin said #41 (comment) , link tags get removed ... so putting them into the stache file dont work.
or do i something missunderstand?

@matthewp
Copy link
Contributor

matthewp commented Feb 7, 2018

In 2.0 you'll be able to keep elements in the DOM using a special data attribute. This is explained in the readme:

https://github.com/donejs/autorender/tree/major#keeping-elements-in-the-dom

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

No branches or pull requests

4 participants