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

SSR and CSS #153

Closed
3 tasks done
Rich-Harris opened this issue Dec 7, 2016 · 1 comment
Closed
3 tasks done

SSR and CSS #153

Rich-Harris opened this issue Dec 7, 2016 · 1 comment

Comments

@Rich-Harris
Copy link
Member

Rich-Harris commented Dec 7, 2016

Right now, the server-side renderer will bug out if it encounters a <style> tag. That's because CSS needs to be handled slightly differently – you can't include the <style> tag with the generated HTML, because it would be duplicated for each instance of a component.

So on the server, we need to gather all the (transformed, for scoped styles) CSS together for a component plus each of its nested components, in a form that lets us spit it out into a .css file (particularly useful in light of #152). On the client, we need to have a way to not inject <style> tags (injecting them would be harmless but redundant if the server-rendered CSS is already on the page).

Something like this:

// in node.js
require( 'svelte/ssr/register' );

var thing = require( './components/Thing.html' );
var html = thing.render({...});
var css = thing.renderCss();

// in the browser
import Thing from './components/Thing.html';

var thing = new Thing({
  target: document.querySelector( 'main' ),
  css: false
});

One wrinkle: a page could have multiple top-level Svelte apps, which might share components. We need to provide a way for developers to dedupe CSS across those apps, while making the common case (collecting all the CSS together in a single blob) easy. We also need to make it possible to support CSS sourcemaps when we get round to that. So perhaps thing.renderCss() should return an object like this:

var { css, map, components } = thing.renderCss();

console.log( css );
// .foo[svelte-3599223440], [svelte-3599223440] .foo { color: red; }

console.log( map );
// null, but eventually {"version": 3, ...}

console.log( components );
// [
//   { file: '/path/to/components/Thing.html', css: '...', map: null },
//   { file: '/path/to/components/Nested.html', css: '...', map: null }
// ]

Have I missed anything? Does that seem sensible?

  • Implement css: false
  • Implement renderCss()
  • Add svelte-[uniqueid] attributes to elements at server-render time
@Ryuno-Ki
Copy link

Ryuno-Ki commented Dec 7, 2016

injecting them would be harmless but redundant if the server-rendered CSS is already on the page

It depends. Yes, they would be forbidden by CSP. On the other hand, Google pushes for "critical CSS" which is inline <style> responsible for the parts of a website "above the fold" (that is, visible without scrolling and ignoring anchors in an URL). As I mentioned in #152 there are upsides and downsides. I tend to use CSS files.

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

No branches or pull requests

2 participants