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

Lit@2 Shady DOM styles not present when pre-rendering with puppeteer #675

Closed
3 of 8 tasks
thescientist13 opened this issue Jul 29, 2021 · 6 comments · Fixed by #611 or #719
Closed
3 of 8 tasks

Lit@2 Shady DOM styles not present when pre-rendering with puppeteer #675

thescientist13 opened this issue Jul 29, 2021 · 6 comments · Fixed by #611 or #719
Assignees
Labels
Milestone

Comments

@thescientist13
Copy link
Member

thescientist13 commented Jul 29, 2021

Type of Change

  • New Feature Request
  • Documentation / Website
  • Improvement / Suggestion
  • Bug
  • Other (please clarify below)

Summary

Making a separate issue after observing this in #611 (comment) and also being able to reproduce in thegreenhouseio/www.thegreenhouse.io#234, but essentially the issue boils down to that puppeteer is not putting <style> tags for Web Components in the <head> of the document anymore, which means if JS is disabled or Greenwood's static optimization setting is used, those fallback styles are no longer in index.html and thus everything looks borked, as you can see here.
Screen Shot 2021-07-28 at 11 21 26 AM

I think the issue comes down to something new that I think Lit@2 is doing, which is introducing the concept of Declarative Shadow DOM to their templating engine, to support SSR and that my initial hunch is that our old version of puppeteer doesn't know how to handle that?

So as mentioned, one way to still use DSD / Lit@2 now would be to just not use static, e.g.
Screen Shot 2021-07-29 at 3 14 10 PM
Screen Shot 2021-07-29 at 3 22 38 PM

Details

So to get a little technical first, the best way to understand what is happening I think is to first see what is happening. Basically, this is what index.html looks like now via puppeteer.

<!DOCTYPE html><html lang="en" prefix="og:http://ogp.me/ns#">
          <script data-state="apollo">
            window.__APOLLO_STATE__ = true;
          </script>
          
          <head>
            <script src="/webcomponents-loader.js"></script>
        
        <!-- Shady DOM styles for eve-container --><style scope="eve-container">eve-container .container.eve-container {
  margin-right: auto;     margin-left: auto;     padding-left: 15px;     padding-right: 15px;
}

eve-container .container-fluid.eve-container {
  margin-right: auto;     margin-left: auto;     padding-left: 15px;     padding-right: 15px;
}

@media (--screen-xs) {
eve-container .container.eve-container {
  width: calc(100% - 30px);
}

}

@media (--screen-sm) {
eve-container .container.eve-container {
  width: 540px;
}

}

@media (--screen-md) {
eve-container .container.eve-container {
  width: 720px;
}

}

@media (--screen-lg) {
eve-container .container.eve-container {
  width: 960px;
}

}

@media (--screen-xl) {
eve-container .container.eve-container {
  width: 1140px;
}

}</style><!-- Shady DOM styles for app-social-icons --><style scope="app-social-icons">app-social-icons {
  display: flex;   justify-content: space-around;   flex-direction: row;
}

app-social-icons .icons.app-social-icons {
  margin: auto;
}

app-social-icons .slack-icon.app-social-icons {
  padding: 0 1rem 0 1.25rem;
}

@media (max-width: 768px) {
app-social-icons {
  flex-direction: row
}

}</style><!-- Shady DOM styles for app-header --><style scope="app-header">app-header .header.app-header {
  background-color: #192a27;     min-height: 30px;     padding: 10px;     font-size: 1.2rem;
}

app-header .header.app-header a.app-header {
  color: white;       text-decoration: none;
}

app-header .header.app-header .project-name.app-header {
  margin: -2px 0 auto;       padding: 0;       padding-top: 4px;       display: inline-block;       color: #201e2e;       font-weight: bold;
}

app-header .header.app-header .head-wrap.app-header {
  display: flex;       align-items: center;       flex-wrap: wrap;       justify-content: space-between;
}

@media (max-width: 768px) {
app-header .header.app-header .head-wrap.app-header {
  flex-direction: column;         text-align: center
}

}

app-header .header.app-header nav.app-header {
  justify-items: left;       width: 55%;
}

app-header .header.app-header nav.app-header ul.app-header {
  padding: 0;         margin: 0;         list-style: none;         text-align: center;
}

app-header .header.app-header nav.app-header ul.app-header li.app-header {
  margin: 0;           color: white;           display: inline-block;           padding: 10px;
}

app-header .header.app-header nav.app-header ul.app-header li.app-header:hover,app-header .header.app-header nav.app-header ul.app-header li.app-header:focus {
  color: #f9e7ca;
}

app-header .header.app-header nav.app-header ul.app-header li.app-header:hover a.app-header,app-header .header.app-header nav.app-header ul.app-header li.app-header:focus a.app-header {
  color: green;
}

@media (max-width: 768px) {
app-header .header.app-header nav.app-header {
  width: 100%
}

}

app-header .header.app-header .brand.app-header {
  justify-items: left;       padding: 10px;
}

app-header .header.app-header .brand.app-header img.app-header {
  float: left;         height: 30px;         width: 30px;         margin-right: 0.5rem;
}

app-header .header.app-header .social.app-header {
  margin-left: auto;       text-align: right;
}

app-header .header.app-header .social.app-header img.app-header {
  width: 84px;         height: 20px;
}</style><!-- Shady DOM styles for app-footer --><style scope="app-footer">app-footer {
  grid-area: footer;
}

app-footer .footer.app-footer {
  background-color: #192a27;     min-height: 30px;     padding-top: 10px;
}

app-footer .footer.app-footer h4.app-footer {
  width: 90%;       margin: 0 auto!important;       padding: 0;       text-align: center;
}

app-footer .footer.app-footer a.app-footer {
  color: white;       text-decoration: none;
}

app-footer .footer.app-footer span.separator.app-footer {
  color: white;
}</style><!-- Shady DOM styles for app-card --><style scope="app-card">app-card {
  position: relative;   display: flex;   flex-direction: column;   min-width: 0;   word-wrap: break-word;   background-color: #fff;   background-clip: initial;   text-align: center;
}

app-card slot.app-card {
  text-align: left;     font-size: 1rem;
}

app-card .card-img-top.app-card {
  background-size: cover;     background-position-x: center;     background-position-y: center;
}

app-card .card-img-top.app-card img.app-card {
  width: 200px;       height: 200px;       max-width: 200px;
}</style><!-- Shady DOM styles for eve-button --><style scope="eve-button-1">.eve-button-1 .btn.eve-button {
  margin: 2px;     border: 1px solid green;     color: green;     background-color: white;     text-decoration:none;     position:relative;     display: inline-block;     border-radius: 0px;
}

.eve-button-1 .btn.eve-button:hover {
  background-color: green;       color: white;       border: 1px solid green;
}

.eve-button-1 .btn-xs.eve-button {
  padding:5px;     font-size:12px;
}

.eve-button-1 .btn-sm.eve-button {
  padding:5px;     font-size:16px;
}

.eve-button-1 .btn-md.eve-button {
  padding:10px;     font-size:20px;
}

.eve-button-1 .btn-lg.eve-button {
  padding:15px;     font-size:25px;
}</style><!-- Shady DOM styles for app-banner --><style scope="app-banner">app-banner .btn.app-banner {
  display: inline-block;   border-radius: 10px;   font-size: 1.2rem;   padding: 0.75rem;   color: white;   background-color: #201e2e;   border: 1px solid white;   transition: 0.3s;
}

app-banner .btn.app-banner:hover,app-banner .btn.app-banner:focus {
  background-color: #425d58;   border: 1px solid white;
}

@keyframes fadeOut {
from {
  opacity: 1;
}

to {
  opacity: 0;
}

}

@keyframes fadeIn {
from {
  opacity: 0;
}

to {
  opacity: 1;
}

}

app-banner .banner.app-banner {
  background-color: #fff;     min-height: 60vh;
}

app-banner .banner.app-banner .content.app-banner {
  padding: 5vh 10px;       font-size: 1.7rem;       text-align: center;
}

app-banner .banner.app-banner .content.app-banner hr.app-banner {
  border-radius: 25px;         border-style: none;         height: 3px;         margin: 0 auto;         background-color: white;         border: 1px solid rgba(0, 0, 0, 0.6);         width: 160px;
}

app-banner .banner.app-banner .content.app-banner h1.app-banner {
  font-size: 3.5rem;         color: #201e2e;
}

app-banner .banner.app-banner .content.app-banner h3.app-banner {
  padding-top: 10px;         color: #201e2e;
}

app-banner .banner.app-banner .content.app-banner img.app-banner {
  width: 300px;         height: 300px;
}

@media screen and (prefers-reduced-motion: reduce) {
app-banner .banner.app-banner span.off.app-banner {
  animation: none;
}

@media (prefers-reduced-motion) {
app-banner .banner.app-banner span.off.app-banner {
  animation: 0
}

}

}

app-banner .banner.app-banner span.off.app-banner {
  animation: 1s fadeOut ease-in-out;
}

@media screen and (prefers-reduced-motion: reduce) {
app-banner .banner.app-banner span.on.app-banner {
  animation: none;
}

}

app-banner .banner.app-banner span.on.app-banner {
  animation: 1s fadeIn linear;
}

@media (max-width: 980px) {
app-banner .banner.app-banner {
  min-height: 40vh;
}

app-banner .banner.app-banner .content.app-banner {
  font-size: 1.5rem;
}

app-banner .banner.app-banner .content.app-banner h1.app-banner {
  font-size: 3rem;
}

app-banner .banner.app-banner .content.app-banner img.app-banner {
  width: 250px;           height: 250px;
}

}

@media (max-width: 756px) {
app-banner .banner.app-banner {
  padding: 0;
}

app-banner .banner.app-banner .content.app-banner {
  margin-top: 0;
}

}</style><style>body {transition: opacity ease-in 0.2s; } 
body[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } 
</style>
            
            
        <title>Greenwood</title>
        
    
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="description" content="A modern and performant static site generator supporting Web Component based development">
<meta name="twitter:site" content="@PrjEvergreen">
<meta property="og:title" content="Greenwood">
<meta property="og:type" content="website">
<meta property="og:url" content="https://www.greenwoodjs.io">
<meta property="og:image" content="https://s3.amazonaws.com/hosted.greenwoodjs.io/greenwood-logo.png">
<meta property="og:description" content="A modern and performant static site generator supporting Web Component based development">
<link rel="shortcut icon" href="/assets/favicon.ico">
<link rel="icon" href="/assets/favicon.ico">
<meta name="google-site-verification" content="4rYd8k5aFD0jDnN0CCFgUXNe4eakLP4NnA18mNnK5P0">

    
                  <style>
                    @font-face{font-family:Source Sans Pro;font-style:normal;font-weight:400;font-display:swap;src:local("Source Sans Pro Regular"),local("SourceSansPro-Regular"),url(/assets/fonts/source-sans-pro-v13-latin-regular.woff2) format("woff2"),url(/assets/fonts/source-sans-pro-v13-latin-regular.woff) format("woff"),url(/assets/fonts/source-sans-pro-v13-latin-regular.ttf) format("truetype")}
                  </style>
                
    
                  <style>
                    @font-face{font-family:Source Sans Pro;font-style:normal;font-weight:400;font-display:swap;src:local("Source Sans Pro Regular"),local("SourceSansPro-Regular"),url(/assets/fonts/source-sans-pro-v13-latin-regular.woff2) format("woff2"),url(/assets/fonts/source-sans-pro-v13-latin-regular.woff) format("woff"),url(/assets/fonts/source-sans-pro-v13-latin-regular.ttf) format("truetype")}*{margin:0;padding:0;text-decoration:none}html{background-color:#fff}body{font-family:Source Sans Pro,sans-serif;line-height:1.4}img{width:100%}h2,h3,h4,h5{margin-top:1.5rem!important;margin-bottom:1.5rem!important;color:#201e2e}ol,ul{padding-left:20px}p{margin:20px 0}ul>li{margin:10px 0}a .title{text-decoration:underline}a .step{margin:2px}p>code{color:#2d3d3a;font-weight:800}.gwd-wrapper .single-column{margin:inherit;color:#000}
                  </style>
                

      
                  <style>
                    code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}
                  </style>
                

      
                  <style>
                    h3{color:green}.gwd-content{background-color:#fff;min-height:300px;font-size:1.2rem}.gwd-content h3{font-size:2rem;margin:5px 0}.gwd-content a{color:#201e2e}.message{padding:2rem;text-align:center;margin:0 auto}.message hr{margin-top:4rem}@media (max-width:768px){.message{padding:0}}.quickstart{width:90%;text-align:center;margin:4rem auto}.quickstart p{max-width:60ch;margin:2rem auto auto}.cards{display:flex;justify-content:space-around;flex-direction:row;margin:20px -.25rem 3rem}@media (max-width:1024px){.cards{flex-direction:column}}#gwd-message-wrapper{background-color:#504b65}#gwd-message-wrapper h2{color:#fff;max-width:60ch;margin:auto}@media (max-width:768px){#gwd-message-wrapper h2{padding-top:2rem}}.mini-card{width:200px;margin:1.5rem;border:.5px solid #dddde1;border-radius:20px;background-color:#fff;display:flex;align-items:center;padding:2rem;box-shadow:0 1.3px 2.7px rgba(0,0,0,.065),0 3.4px 6.9px rgba(0,0,0,.093),0 6.9px 14.2px rgba(0,0,0,.117),0 14.2px 29.2px rgba(0,0,0,.145),0 39px 80px rgba(0,0,0,.21)}.min-card-container{display:flex;justify-content:center;flex-wrap:wrap;max-width:1200px;margin:auto}app-card{margin:1.5rem;padding:2rem;border:.5px solid #dddde1;border-radius:20px;box-shadow:0 2px 3.6px rgba(0,0,0,.014),0 5.6px 10px rgba(0,0,0,.02),0 13.6px 24.1px rgba(0,0,0,.026),0 45px 80px rgba(0,0,0,.04)}
                  </style>
                
    
    

    <style>
      .gwd-content-outlet {
        min-height: 100vh
      };
    </style>

    <script type="module">import"/lit-element.5d109b2b.js";import"/eve-container.2e10f408.js";//# sourceMappingURL=756510913-scratch.b55a699e.js.map
</script>
    
    
    

          
                <script type="module">
                  import{L as e,h as t,c as o,u as n}from"/lit-element.5d109b2b.js";import"/eve-container.2e10f408.js";var r=":host .btn{display:inline-block;border-radius:10px;font-size:1.2rem;padding:.75rem;color:#fff;background-color:#201e2e;border:1px solid #fff;transition:.3s}:host .btn:focus,:host .btn:hover{background-color:#425d58;border:1px solid #fff}";customElements.define("eve-button",class extends e{static get properties(){return{href:{type:String},onClick:{type:Function},size:{type:String},style:{type:String}}}updated(e){const t=this.shadowRoot;Array.from(t.childNodes).forEach(e=>{"STYLE"===e.nodeName?e.textContent+=this.style:"A"===e.nodeName&&(e.style=this.style)})}render(){const{size:e,href:o,onClick:n}=this;return t`
    <style>
      ${":host .btn{margin:2px;border:1px solid var(--btn-border-color,var(--primary-color,green));color:var(--btn-text-color,var(--primary-color,green));background-color:var(--btn-background,var(--secondary-color,#fff));text-decoration:none;position:relative;display:inline-block;border-radius:var(--btn-border-radius,0)}:host .btn:hover{background-color:var(--btn-hover-background-color,var(--primary-color,green));color:var(--btn-hover-text-color,var(--secondary-color,#fff));border:1px solid var(--btn-hover-border-color,var(--primary-color,green))}:host .btn-xs{padding:5px;font-size:12px}:host .btn-sm{padding:5px;font-size:16px}:host .btn-md{padding:10px;font-size:20px}:host .btn-lg{padding:15px;font-size:25px}"}
    </style>
      ${o?t`
          <a class="btn btn-${e}" href="${o}">
            <slot></slot>
          </a>
          `:t`
          <a class="btn btn-${e}" href="#" @click="${n}">
            <slot></slot>
          </a>
        `}
    `}});customElements.define("app-banner",class extends e{constructor(){super(),this.currentProjectIndex=0,this.animateState="on",this.projectTypes=["blog","portfolio","website","web app","marketing site","small business"]}static get styles(){return o`
      ${n(r)}
      ${n("@keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}:host .banner{background-color:#fff;min-height:60vh}:host .banner .content{padding:5vh 10px;font-size:1.7rem;text-align:center}:host .banner .content hr{border-radius:25px;height:3px;margin:0 auto;background-color:#fff;border:1px solid rgba(0,0,0,.6);width:160px}:host .banner .content h1{font-size:3.5rem;color:#201e2e}:host .banner .content h3{padding-top:10px;color:#201e2e}:host .banner .content img{width:300px;height:300px}@media screen and (prefers-reduced-motion:reduce){:host .banner span.off{animation:none}@media (prefers-reduced-motion){:host .banner span.off{animation:0}}}:host .banner span.off{animation:fadeOut 1s ease-in-out}@media screen and (prefers-reduced-motion:reduce){:host .banner span.on{animation:none}}:host .banner span.on{animation:fadeIn 1s linear}@media (max-width:980px){:host .banner{min-height:40vh}:host .banner .content{font-size:1.5rem}:host .banner .content h1{font-size:3rem}:host .banner .content img{width:250px;height:250px}}@media (max-width:756px){:host .banner{padding:0}:host .banner .content{margin-top:0}}")}
    `}cycleProjectTypes(){this.currentProjectIndex=this.currentProjectIndex+=1,this.currentProjectIndex>=this.projectTypes.length&&(this.currentProjectIndex=0)}firstUpdated(){setInterval(()=>{this.animateState="off",this.update(),setTimeout(()=>{this.cycleProjectTypes(),this.animateState="on",this.update()},1e3)},3e3)}render(){const e=this.projectTypes[this.currentProjectIndex];return t`
      <div class='banner'>
        <eve-container>
          <div class='content'>
            <img 
              src="././assets/greenwood-logo-300w.png" 
              alt="Greenwood Logo"
              srcset="././assets/greenwood-logo-300w.png 1x,
                      ././assets/greenwood-logo-500w.png 2x,
                      ././assets/greenwood-logo-750w.png 3x,
                      ././assets/greenwood-logo-1000w.png 4x,
                      ././assets/greenwood-logo-1500w.png 5x"/>

            <h3>The static site generator for your. . . <br /><span class="${this.animateState}">${e}.</span></h3>

            <eve-button size="md" href="/getting-started/" style="${r}">Get Started</eve-button>
          </div>
        </eve-container>
      </div>
    `}});
//# sourceMappingURL=banner.e9cedcae.js.map

                </script>
              

          

        

        
    
  
          
                <script type="module">
                  document.addEventListener("click",(function(e){const t=(e.path&&e.path[0]?e.path[0].href:e.originalTarget&&e.originalTarget.href?e.originalTarget.href:"")||"",o=t.indexOf(window.location.hostname)>=0||t.indexOf("localhost")>=0;if(""!==t&&o){e.preventDefault();const o=t.replace(window.location.origin,""),n=Array.from(document.getElementsByTagName("greenwood-route")).filter(e=>e.getAttribute("data-route")===o)[0];n.getAttribute("data-template")===window.__greenwood.currentTemplate?(window.__greenwood.currentTemplate=n.getAttribute("data-template"),n.loadRoute()):window.location.href=t}}));class e extends HTMLElement{loadRoute(){const e=this.getAttribute("data-route"),t=this.getAttribute("data-key");fetch(t).then(e=>e.text()).then(t=>{history.pushState(t,e,e),document.getElementsByTagName("router-outlet")[0].innerHTML=t})}}class t extends HTMLElement{}customElements.define("greenwood-route",e),customElements.define("router-outlet",t);
//# sourceMappingURL=router.e74094cc.js.map

                </script>
              

          <script>
            window.__greenwood = window.__greenwood || {};
            
            window.__greenwood.currentTemplate = "/";
          </script> 
          </head>
        

  
          <body>

            
            <router-outlet>
              

    <div class="gwd-wrapper">
      <app-header><!---->
      <header class="header style-scope app-header">
        <eve-container fluid="" class="style-scope app-header"><!---->
      
      <div class="container-fluid style-scope eve-container">
        
          <div class="head-wrap style-scope app-header">

            <div class="brand style-scope app-header">
              <a href="https://projectevergreen.github.io" target="_blank" rel="noopener noreferrer" onclick="getOutboundLink('https://projectevergreen.github.io');" class="style-scope app-header">
                <img src="../../assets/evergreen.svg" alt="Greenwood logo" class="style-scope app-header">
              </a>
              <div class="project-name style-scope app-header">
                <a href="/" class="style-scope app-header">Greenwood</a>
              </div>
            </div>

            <nav class="style-scope app-header">
              <ul class="style-scope app-header">
                <!---->
                    <li class="style-scope app-header"><a class="style-scope app-header" href="/about/" title="Click to visit the About page"><!---->About<!----></a></li>
                  <!---->
                    <li class="style-scope app-header"><a class="style-scope app-header" href="/docs/" title="Click to visit the Docs page"><!---->Docs<!----></a></li>
                  <!---->
                    <li class="style-scope app-header"><a class="style-scope app-header" href="/getting-started/" title="Click to visit the Getting Started page"><!---->Getting Started<!----></a></li>
                  <!---->
                    <li class="style-scope app-header"><a class="style-scope app-header" href="/plugins/" title="Click to visit the Plugins page"><!---->Plugins<!----></a></li>
                  <!---->
                    <li class="style-scope app-header"><a class="style-scope app-header" href="/guides/" title="Click to visit the Guides page"><!---->Guides<!----></a></li>
                  <!---->
              </ul>
            </nav>

            <app-social-icons class="style-scope app-header"><!---->
      <a class="icons style-scope app-social-icons" target="_blank" rel="noreferrer noopener" aria-label="open github page" href="https://github.com/ProjectEvergreen/greenwood" onclick="getOutboundLink('https://github.com/ProjectEvergreen/greenwood');"><!----><svg height="35" viewBox="0 0 16 16" version="1.1" width="35" aria-hidden="true" class="style-scope app-social-icons">
    <path fill-rule="evenodd" fill="white" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38
      0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01
      1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12
      0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82
      2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65
      3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013
      8.013 0 0016 8c0-4.42-3.58-8-8-8z" class="style-scope app-social-icons">
    </path>
  </svg><!----></a>
      
      <a class="icons slack-icon style-scope app-social-icons" target="_blank" rel="noreferrer noopener" aria-label="slack" href="https://join.slack.com/t/thegreenhouseio/shared_invite/enQtMzcyMzE2Mjk1MjgwLTU5YmM1MDJiMTg0ODk4MjA4NzUwNWFmZmMxNDY5MTcwM2I0MjYxN2VhOTEwNDU2YWQwOWQzZmY1YzY4MWRlOGI" onclick="getOutboundLink('https://join.slack.com/t/thegreenhouseio/shared_invite/enQtMzcyMzE2Mjk1MjgwLTU5YmM1MDJiMTg0ODk4MjA4NzUwNWFmZmMxNDY5MTcwM2I0MjYxN2VhOTEwNDU2YWQwOWQzZmY1YzY4MWRlOGI')"><!----><svg width="35" height="35" style="fill:white;" viewBox="0 0 54 54" xmlns="http://www.w3.org/2000/svg" class="style-scope app-social-icons">
    <g fill="none" fill-rule="evenodd" class="style-scope app-social-icons">
      <path d="M19.712.133a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376
        5.386h5.376V5.52A5.381 5.381 0 0 0 19.712.133m0 14.365H5.376A5.381
        5.381 0 0 0 0 19.884a5.381 5.381 0 0 0 5.376 5.387h14.336a5.381 5.381
        0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386" fill="#fff" class="style-scope app-social-icons"></path>
      <path d="M53.76 19.884a5.381 5.381 0 0 0-5.376-5.386 5.381 5.381 0 0 0-5.376
        5.386v5.387h5.376a5.381 5.381 0 0 0 5.376-5.387m-14.336 0V5.52A5.381 5.381
        0 0 0 34.048.133a5.381 5.381 0 0 0-5.376 5.387v14.364a5.381 5.381 0 0 0
        5.376 5.387 5.381 5.381 0 0 0 5.376-5.387" fill="#fff" class="style-scope app-social-icons"></path>
      <path d="M34.048 54a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0
        0-5.376-5.386h-5.376v5.386A5.381 5.381 0 0 0 34.048 54m0-14.365h14.336a5.381
        5.381 0 0 0 5.376-5.386 5.381 5.381 0 0 0-5.376-5.387H34.048a5.381 5.381
        0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386" fill="#fff" class="style-scope app-social-icons"></path>
      <path d="M0 34.249a5.381 5.381 0 0 0 5.376 5.386 5.381 5.381 0 0 0
        5.376-5.386v-5.387H5.376A5.381 5.381 0 0 0 0 34.25m14.336-.001v14.364A5.381
        5.381 0 0 0 19.712 54a5.381 5.381 0 0 0 5.376-5.387V34.25a5.381 5.381
        0 0 0-5.376-5.387 5.381 5.381 0 0 0-5.376 5.387" fill="#fff" class="style-scope app-social-icons"></path>
    </g>
  </svg><!----></a>
      
      <a target="_blank" rel="noreferrer noopener" aria-label="open twitter page" class="style-scope app-social-icons" href="https://twitter.com/PrjEvergreen" onclick="getOutboundLink('https://twitter.com/PrjEvergreen')"><!----><!--?xml version="1.0" ?-->
  
  <svg enable-background="new 0 0 56.693 56.693" height="40px" id="Layer_1" version="1.1" viewBox="0 0 56.693 56.693" width="40px" fill="white" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="style-scope app-social-icons">
      <path d="M28.348,5.157c-13.6,0-24.625,11.027-24.625,24.625c0,13.6,11.025,24.623,24.625,24.623c13.6,0,24.623-11.023,24.623-24.623
        C52.971,16.184,41.947,5.157,28.348,5.157z M40.752,24.817c0.013,0.266,0.018,0.533,0.018,0.803c0,8.201-6.242,17.656-17.656,17.656
        c-3.504,0-6.767-1.027-9.513-2.787c0.486,0.057,0.979,0.086,1.48,0.086c2.908,0,5.584-0.992,7.707-2.656
        c-2.715-0.051-5.006-1.846-5.796-4.311c0.378,0.074,0.767,0.111,1.167,0.111c0.566,0,1.114-0.074,1.635-0.217
        c-2.84-0.57-4.979-3.08-4.979-6.084c0-0.027,0-0.053,0.001-0.08c0.836,0.465,1.793,0.744,2.811,0.777
        c-1.666-1.115-2.761-3.012-2.761-5.166c0-1.137,0.306-2.204,0.84-3.12c3.061,3.754,7.634,6.225,12.792,6.483
        c-0.106-0.453-0.161-0.928-0.161-1.414c0-3.426,2.778-6.205,6.206-6.205c1.785,0,3.397,0.754,4.529,1.959
        c1.414-0.277,2.742-0.795,3.941-1.506c-0.465,1.45-1.448,2.666-2.73,3.433c1.257-0.15,2.453-0.484,3.565-0.977
        C43.018,22.849,41.965,23.942,40.752,24.817z" class="style-scope app-social-icons"></path>
  </svg><!----></a>
    <!----></app-social-icons>

          </div>
        
      </div>
    <!----></eve-container>
      </header>
    <!----></app-header>

      

    <div class="gwd-content-outlet">

      <app-banner><!---->
      <div class="banner style-scope app-banner">
        <eve-container class="style-scope app-banner"><!---->
      
      <div class="container style-scope eve-container">
        
          <div class="content style-scope app-banner">
            <img src="../../assets/greenwood-logo-300w.png" alt="Greenwood Logo" srcset="../../assets/greenwood-logo-300w.png 1x,
                      ../../assets/greenwood-logo-500w.png 2x,
                      ../../assets/greenwood-logo-750w.png 3x,
                      ../../assets/greenwood-logo-1000w.png 4x,
                      ../../assets/greenwood-logo-1500w.png 5x" class="style-scope app-banner">

            <h3 class="style-scope app-banner">The static site generator for your. . . <br class="style-scope app-banner"><span class="on style-scope app-banner"><!---->portfolio.</span></h3>

            <eve-button size="md" href="/getting-started/" class="style-scope app-banner x-scope eve-button-1" style="/* stylelint-disable a11y/media-prefers-reduced-motion */ :host .btn {   display: inline-block;   border-radius: 10px;   font-size: 1.2rem;   padding: 0.75rem;   color: white;   background-color: #201e2e;   border: 1px solid white;   transition: 0.3s; }  :host .btn:hover, :host .btn:focus {   background-color: #425d58;   border: 1px solid white; }"><!---->
    
      
          <a class="btn btn-md style-scope eve-button" href="/getting-started/" style="">
            Get Started
          </a>
          
    <!----></eve-button>
          </div>
        
      </div>
    <!----></eve-container>
      </div>
    <!----></app-banner>

      <div class="gwd-content-wrapper">

          <div class="gwd-page-template gwd-content">
            <div id="gwd-message-wrapper">
              <div class="message">
                <h2>Greenwood is a modern and performant static site generator for Web Component based development.</h2>

                <div class="min-card-container">
                  <div class="mini-card"><p>Prerendered, <a href="/about/how-it-works/" title="How It Works" target="_blank" rel="noopener noreferrer">even your Web Components</a></p></div>
                  <div class="mini-card"><p><a href="/docs/layouts/" title="Layout docs" target="_blank" rel="noopener noreferrer">Filesystem based routing</a></p></div>
                  <div class="mini-card"><p>A fast, unbundled, local development workflow</p></div>
                  <div class="mini-card"><p><a href="/about/goals/" title="Goals" target="_blank" rel="noopener noreferrer">Easy to get started with</a></p></div>
                  <div class="mini-card"><p>Extensible <a href="/plugins/" title="Plugins" target="_blank" rel="noopener noreferrer">plugin system</a></p></div>
                  <div class="mini-card"><p><a href="/docs/data/" title="Data docs" target="_blank" rel="noopener noreferrer">Content as data</a> with GraphQL</p></div>
                </div>
              </div>
            </div>

            <div class="quickstart">
              <h2>Quick Start Example</h2>
              <pre class="language-bash">                <code class="language-bash">
                  # with NodeJS already installed
                  # create a pages directory for your content
                  $ mkdir -p src/pages

                  # create an index.md file as your home page
                  $ echo "## hello world" &gt; src/pages/index.md

                  # run one of Greenwood's commands, and that's it!
                  $ npx @greenwood/cli develop
                </code>
              </pre>
              <p>For anyone new to Greenwood, we encourage you go through our <a href="/getting-started/">Getting Started</a> guide, or to get right to work, head on over to our <a href="/docs/">documentation</a>.</p>
            </div>

            <div class="cards">
              <app-card title="The Modern Web" img="../assets/webcomponents.svg"><!---->
      
        <div class="card-img-top style-scope app-card">
          <img loading="lazy" class="style-scope app-card" src="../assets/webcomponents.svg" alt="The Modern Web">
        </div>
      
      
        <h3 class="style-scope app-card"><!---->The Modern Web<!----></h3>
      
      <p slot="cardcontent">Modern browsers, combined with recent advancements in web standards like <strong>Web Components</strong>, <strong>ES Modules</strong>, and <strong>CSS Custom Properties</strong>, bring a lot of native power and features to the web browsers we all use now.  With less need to put tools in front of your code, Greenwood makes completing your goals easier, faster, and less complicated.</p>
    <!----></app-card>

              <app-card title="Ecosystem" img="../assets/nodejs.png"><!---->
      
        <div class="card-img-top style-scope app-card">
          <img loading="lazy" class="style-scope app-card" src="../assets/nodejs.png" alt="Ecosystem">
        </div>
      
      
        <h3 class="style-scope app-card"><!---->Ecosystem<!----></h3>
      
      <p slot="cardcontent">While the web provides a lot out of the box, we want everyone to be able to reach for those additional packages we need that help us achieve our goal of building great things.  <strong>NodeJS</strong>, along with <strong>npm</strong>, provides a great developer experience and ecosystem to leverage when  building web projects.</p>
    <!----></app-card>

              <app-card title="Keeping It Simple" img="../assets/simple.png"><!---->
      
        <div class="card-img-top style-scope app-card">
          <img loading="lazy" class="style-scope app-card" src="../assets/simple.png" alt="Keeping It Simple">
        </div>
      
      
        <h3 class="style-scope app-card"><!---->Keeping It Simple<!----></h3>
      
      <p slot="cardcontent">Greenwood is on a mission to provide the best web development experience, to make sure content is easy to create, and that going live is a breeze.  Keeping things simple is a part of that mission, and while we levarge some open source tool to achieve all this, we intend to avoid the meta framework trend and aim keep to a lean(er) core over time.</p>
    <!----></app-card>
            </div>

          </div>
      </div>

    </div>

  
      
      <app-footer><!---->
      <footer class="footer style-scope app-footer">
        <h4 class="style-scope app-footer">
          <a href="/" class="style-scope app-footer">Greenwood v0.14.2<!----></a> <span class="separator style-scope app-footer"></span> <a href="https://www.netlify.com/" class="style-scope app-footer">This site is powered by Netlify</a>
        </h4>
      </footer>
    <!----></app-footer>
    </div>

     ....

          </body>
        </html>

And here's what it looks like in #611 (notice the absence of <style> blocks in the <head> and duplicated <app-header> tags)

<!DOCTYPE html><html lang="en" prefix="og:http://ogp.me/ns#">
          <script data-state="apollo">
            window.__APOLLO_STATE__ = true;
          </script>
          
          
                        
                        
                        
                        
                        
                          
                          
                          
                          <head>
                          <link rel="preload" href="/styles/home.20474824.css" as="style" crossorigin="anonymous"></link>
                        
                          <link rel="preload" href="/prism-tomorrow.18498422.css" as="style" crossorigin="anonymous"></link>
                        
                          <link rel="preload" href="/styles/theme.10782226.css" as="style" crossorigin="anonymous"></link>
                        
                          <link rel="preload" href="/assets/fonts/source-sans-pro.17795069.css" as="style" crossorigin="anonymous"></link>
                        
                        <link rel="modulepreload" href="/router.e74094cc.js" as="script">
                      
                        <link rel="modulepreload" href="/card.a29c3d07.js" as="script">
                      
                        <link rel="modulepreload" href="/banner.b7bc4d1e.js" as="script">
                      
                        <link rel="modulepreload" href="/header.f1e12ff9.js" as="script">
                      
                        <link rel="modulepreload" href="/footer.69630483.js" as="script">
                      
            <script src="/webcomponents-loader.js"></script>
        
        <!-- Shady DOM styles for eve-container --><!-- Shady DOM styles for app-social-icons --><!-- Shady DOM styles for app-header --><!-- Shady DOM styles for eve-button --><!-- Shady DOM styles for app-banner --><!-- Shady DOM styles for app-card --><!-- Shady DOM styles for app-footer --><style>body {transition: opacity ease-in 0.2s; } 
body[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } 
</style>
            
            
        <title>Greenwood</title>
        
    
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="description" content="A modern and performant static site generator supporting Web Component based development">
<meta name="twitter:site" content="@PrjEvergreen">
<meta property="og:title" content="Greenwood">
<meta property="og:type" content="website">
<meta property="og:url" content="https://www.greenwoodjs.io">
<meta property="og:image" content="https://s3.amazonaws.com/hosted.greenwoodjs.io/greenwood-logo.png">
<meta property="og:description" content="A modern and performant static site generator supporting Web Component based development">
<link rel="shortcut icon" href="/assets/favicon.ico">
<link rel="icon" href="/assets/favicon.ico">
<meta name="google-site-verification" content="4rYd8k5aFD0jDnN0CCFgUXNe4eakLP4NnA18mNnK5P0">

    <link rel="stylesheet" href="/assets/fonts/source-sans-pro.17795069.css">
    <link rel="stylesheet" href="/styles/theme.10782226.css">

      <link rel="stylesheet" href="/prism-tomorrow.18498422.css">

      <link rel="stylesheet" href="/styles/home.20474824.css">
    
    

    <style>
      .gwd-content-outlet {
        min-height: 100vh
      };
    </style>

    <script type="module">import"/lit-element.a1f12400.js";import"/eve-container.f656ed96.js";</script>
    
    <script type="module" src="/footer.69630483.js"></script>
    <script type="module" src="/header.f1e12ff9.js"></script>

          <script type="module" src="/banner.b7bc4d1e.js"></script>

          <script type="module" src="/card.a29c3d07.js"></script>

        

        
    
  
          <script type="module" src="/router.e74094cc.js"></script>

          <script>
            window.__greenwood = window.__greenwood || {};
            
            window.__greenwood.currentTemplate = "/";
          </script> 
          </head>
        

  
          <body>

            
            <router-outlet>
              

    <div class="gwd-wrapper">
      <app-header><!---->
      <header class="header style-scope app-header">
        <eve-container fluid="" class="style-scope app-header"><!---->
      <style class="style-scope eve-container">
      <!---->@custom-media --screen-xs (max-width: 576px); @custom-media --screen-sm (min-width: 576px); @custom-media --screen-md (min-width: 768px); @custom-media --screen-lg (min-width: 992px); @custom-media --screen-xl (min-width: 1200px);  :host .container {     margin-right: auto;     margin-left: auto;     padding-left: 15px;     padding-right: 15px;   }  :host .container-fluid {     margin-right: auto;     margin-left: auto;     padding-left: 15px;     padding-right: 15px;   }  @media (--screen-xs) {     :host .container {       width: calc(100% - 30px);     }   }  @media (--screen-sm) {     :host .container {       width: 540px;     }   }  @media (--screen-md) {     :host .container {       width: 720px;     }   }  @media (--screen-lg) {     :host .container {       width: 960px;     }   }  @media (--screen-xl) {     :host .container {       width: 1140px;     }   }
      <!----></style>
      <div class="container-fluid style-scope eve-container">
        
          <div class="head-wrap style-scope app-header">

            <div class="brand style-scope app-header">
              <a href="https://projectevergreen.github.io" target="_blank" rel="noopener noreferrer" onclick="getOutboundLink('https://projectevergreen.github.io');" class="style-scope app-header">
                <img src="../../assets/evergreen.svg" alt="Greenwood logo" class="style-scope app-header">
              </a>
              <div class="project-name style-scope app-header">
                <a href="/" class="style-scope app-header">Greenwood</a>
              </div>
            </div>

            <nav class="style-scope app-header">
              <ul class="style-scope app-header">
                <!--?lit

    <div class="gwd-wrapper">
      <app-header><!---->
      <header class="header style-scope app-header">
        <eve-container fluid="" class="style-scope app-header"><!---->
      <style class="style-scope eve-container">
      <!---->@custom-media --screen-xs (max-width: 576px); @custom-media --screen-sm (min-width: 576px); @custom-media --screen-md (min-width: 768px); @custom-media --screen-lg (min-width: 992px); @custom-media --screen-xl (min-width: 1200px);  :host .container {     margin-right: auto;     margin-left: auto;     padding-left: 15px;     padding-right: 15px;   }  :host .container-fluid {     margin-right: auto;     margin-left: auto;     padding-left: 15px;     padding-right: 15px;   }  @media (--screen-xs) {     :host .container {       width: calc(100% - 30px);     }   }  @media (--screen-sm) {     :host .container {       width: 540px;     }   }  @media (--screen-md) {     :host .container {       width: 720px;     }   }  @media (--screen-lg) {     :host .container {       width: 960px;     }   }  @media (--screen-xl) {     :host .container {       width: 1140px;     }   }
      <!----></style>
      <div class="container-fluid style-scope eve-container">
        
          <div class="head-wrap style-scope app-header">

            <div class="brand style-scope app-header">
              <a href="https://projectevergreen.github.io" target="_blank" rel="noopener noreferrer" onclick="getOutboundLink('https://projectevergreen.github.io');" class="style-scope app-header">
                <img src="../../assets/evergreen.svg" alt="Greenwood logo" class="style-scope app-header">
              </a>
              <div class="project-name style-scope app-header">
                <a href="/" class="style-scope app-header">Greenwood</a>
              </div>
            </div>

            <nav class="style-scope app-header">
              <ul class="style-scope app-header">
                <!--?lit$1327782744$--><!---->
                    <li class="style-scope app-header"><a href="/about/" title="Click to visit the About page" class="style-scope app-header"><!--?lit$1327782744$-->About</a></li>
                  <!----><!---->
                    <li class="style-scope app-header"><a href="/docs/" title="Click to visit the Docs page" class="style-scope app-header"><!--?lit$1327782744$-->Docs</a></li>
                  <!----><!---->
                    <li class="style-scope app-header"><a href="/getting-started/" title="Click to visit the Getting Started page" class="style-scope app-header"><!--?lit$1327782744$-->Getting Started</a></li>
                  <!----><!---->
                    <li class="style-scope app-header"><a href="/plugins/" title="Click to visit the Plugins page" class="style-scope app-header"><!--?lit$1327782744$-->Plugins</a></li>
                  <!----><!---->
                    <li class="style-scope app-header"><a href="/guides/" title="Click to visit the Guides page" class="style-scope app-header"><!--?lit$1327782744$-->Guides</a></li>
                  <!---->
              </ul>
            </nav>

            <app-social-icons class="style-scope app-header"><!---->
      <a class="icons style-scope app-social-icons" target="_blank" rel="noreferrer noopener" aria-label="open github page" href="https://github.com/ProjectEvergreen/greenwood" onclick="getOutboundLink('https://github.com/ProjectEvergreen/greenwood');"><!--?lit$1327782744$--><svg height="35" viewBox="0 0 16 16" version="1.1" width="35" aria-hidden="true" class="style-scope app-social-icons">
    <path fill-rule="evenodd" fill="white" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38
      0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01
      1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12
      0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82
      2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65
      3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013
      8.013 0 0016 8c0-4.42-3.58-8-8-8z" class="style-scope app-social-icons">
    </path>
  </svg></a>
      
      <a class="icons slack-icon style-scope app-social-icons" target="_blank" rel="noreferrer noopener" aria-label="slack" href="https://join.slack.com/t/thegreenhouseio/shared_invite/enQtMzcyMzE2Mjk1MjgwLTU5YmM1MDJiMTg0ODk4MjA4NzUwNWFmZmMxNDY5MTcwM2I0MjYxN2VhOTEwNDU2YWQwOWQzZmY1YzY4MWRlOGI" onclick="getOutboundLink('https://join.slack.com/t/thegreenhouseio/shared_invite/enQtMzcyMzE2Mjk1MjgwLTU5YmM1MDJiMTg0ODk4MjA4NzUwNWFmZmMxNDY5MTcwM2I0MjYxN2VhOTEwNDU2YWQwOWQzZmY1YzY4MWRlOGI')"><!--?lit$1327782744$--><svg width="35" height="35" style="fill:white;" viewBox="0 0 54 54" xmlns="http://www.w3.org/2000/svg" class="style-scope app-social-icons">
    <g fill="none" fill-rule="evenodd" class="style-scope app-social-icons">
      <path d="M19.712.133a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376
        5.386h5.376V5.52A5.381 5.381 0 0 0 19.712.133m0 14.365H5.376A5.381
        5.381 0 0 0 0 19.884a5.381 5.381 0 0 0 5.376 5.387h14.336a5.381 5.381
        0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386" fill="#fff" class="style-scope app-social-icons"></path>
      <path d="M53.76 19.884a5.381 5.381 0 0 0-5.376-5.386 5.381 5.381 0 0 0-5.376
        5.386v5.387h5.376a5.381 5.381 0 0 0 5.376-5.387m-14.336 0V5.52A5.381 5.381
        0 0 0 34.048.133a5.381 5.381 0 0 0-5.376 5.387v14.364a5.381 5.381 0 0 0
        5.376 5.387 5.381 5.381 0 0 0 5.376-5.387" fill="#fff" class="style-scope app-social-icons"></path>
      <path d="M34.048 54a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0
        0-5.376-5.386h-5.376v5.386A5.381 5.381 0 0 0 34.048 54m0-14.365h14.336a5.381
        5.381 0 0 0 5.376-5.386 5.381 5.381 0 0 0-5.376-5.387H34.048a5.381 5.381
        0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386" fill="#fff" class="style-scope app-social-icons"></path>
      <path d="M0 34.249a5.381 5.381 0 0 0 5.376 5.386 5.381 5.381 0 0 0
        5.376-5.386v-5.387H5.376A5.381 5.381 0 0 0 0 34.25m14.336-.001v14.364A5.381
        5.381 0 0 0 19.712 54a5.381 5.381 0 0 0 5.376-5.387V34.25a5.381 5.381
        0 0 0-5.376-5.387 5.381 5.381 0 0 0-5.376 5.387" fill="#fff" class="style-scope app-social-icons"></path>
    </g>
  </svg></a>
      
      <a target="_blank" rel="noreferrer noopener" aria-label="open twitter page" href="https://twitter.com/PrjEvergreen" onclick="getOutboundLink('https://twitter.com/PrjEvergreen')" class="style-scope app-social-icons"><!--?lit$1327782744$--><!--?xml version="1.0" ?-->
  
  <svg enable-background="new 0 0 56.693 56.693" height="40px" id="Layer_1" version="1.1" viewBox="0 0 56.693 56.693" width="40px" fill="white" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="style-scope app-social-icons">
      <path d="M28.348,5.157c-13.6,0-24.625,11.027-24.625,24.625c0,13.6,11.025,24.623,24.625,24.623c13.6,0,24.623-11.023,24.623-24.623
        C52.971,16.184,41.947,5.157,28.348,5.157z M40.752,24.817c0.013,0.266,0.018,0.533,0.018,0.803c0,8.201-6.242,17.656-17.656,17.656
        c-3.504,0-6.767-1.027-9.513-2.787c0.486,0.057,0.979,0.086,1.48,0.086c2.908,0,5.584-0.992,7.707-2.656
        c-2.715-0.051-5.006-1.846-5.796-4.311c0.378,0.074,0.767,0.111,1.167,0.111c0.566,0,1.114-0.074,1.635-0.217
        c-2.84-0.57-4.979-3.08-4.979-6.084c0-0.027,0-0.053,0.001-0.08c0.836,0.465,1.793,0.744,2.811,0.777
        c-1.666-1.115-2.761-3.012-2.761-5.166c0-1.137,0.306-2.204,0.84-3.12c3.061,3.754,7.634,6.225,12.792,6.483
        c-0.106-0.453-0.161-0.928-0.161-1.414c0-3.426,2.778-6.205,6.206-6.205c1.785,0,3.397,0.754,4.529,1.959
        c1.414-0.277,2.742-0.795,3.941-1.506c-0.465,1.45-1.448,2.666-2.73,3.433c1.257-0.15,2.453-0.484,3.565-0.977
        C43.018,22.849,41.965,23.942,40.752,24.817z" class="style-scope app-social-icons"></path>
  </svg></a>
    <style class="style-scope app-social-icons">
      :host {   display: flex;   justify-content: space-around;   flex-direction: row; }    :host .icons {     margin: auto;   }    :host .slack-icon {     padding: 0 1rem 0 1.25rem;   }    @media (max-width: 768px) {:host {     flex-direction: row }   }
    </style></app-social-icons>

          </div>
        
      </div>
    </eve-container>
      </header>
    <style class="style-scope app-header">
      :host .header {     background-color: #192a27;     min-height: 30px;     padding: 10px;     font-size: 1.2rem;   }      :host .header a {       color: white;       text-decoration: none;     }      :host .header .project-name {       margin: -2px 0 auto;       padding: 0;       padding-top: 4px;       display: inline-block;       color: #201e2e;       font-weight: bold;     }      :host .header .head-wrap {       display: flex;       align-items: center;       flex-wrap: wrap;       justify-content: space-between;     }      @media (max-width: 768px) {      :host .header .head-wrap {         flex-direction: column;         text-align: center     }       }      :host .header nav {       justify-items: left;       width: 55%;     }      :host .header nav ul {         padding: 0;         margin: 0;         list-style: none;         text-align: center;       }      :host .header nav ul li {           margin: 0;           color: white;           display: inline-block;           padding: 10px;         }      :host .header nav ul li:hover,           :host .header nav ul li:focus {             color: #f9e7ca;           }      :host .header nav ul li:hover a, :host .header nav ul li:focus a {               color: green;             }      @media (max-width: 768px) {      :host .header nav {         width: 100%     }       }      :host .header .brand {       justify-items: left;       padding: 10px;     }      :host .header .brand img {         float: left;         height: 30px;         width: 30px;         margin-right: 0.5rem;       }      :host .header .social {       margin-left: auto;       text-align: right;     }      :host .header .social img {         width: 84px;         height: 20px;       } 
    </style></app-header>

      

    <div class="gwd-content-outlet">

      <app-banner><!---->
      <div class="banner style-scope app-banner">
        <eve-container class="style-scope app-banner"><!---->
      <style class="style-scope eve-container">
      <!---->@custom-media --screen-xs (max-width: 576px); @custom-media --screen-sm (min-width: 576px); @custom-media --screen-md (min-width: 768px); @custom-media --screen-lg (min-width: 992px); @custom-media --screen-xl (min-width: 1200px);  :host .container {     margin-right: auto;     margin-left: auto;     padding-left: 15px;     padding-right: 15px;   }  :host .container-fluid {     margin-right: auto;     margin-left: auto;     padding-left: 15px;     padding-right: 15px;   }  @media (--screen-xs) {     :host .container {       width: calc(100% - 30px);     }   }  @media (--screen-sm) {     :host .container {       width: 540px;     }   }  @media (--screen-md) {     :host .container {       width: 720px;     }   }  @media (--screen-lg) {     :host .container {       width: 960px;     }   }  @media (--screen-xl) {     :host .container {       width: 1140px;     }   }
      <!----></style>
      <div class="container style-scope eve-container">
        
          <div class="content style-scope app-banner">
            <img src="../../assets/greenwood-logo-300w.png" alt="Greenwood Logo" srcset="../../assets/greenwood-logo-300w.png 1x,
                      ../../assets/greenwood-logo-500w.png 2x,
                      ../../assets/greenwood-logo-750w.png 3x,
                      ../../assets/greenwood-logo-1000w.png 4x,
                      ../../assets/greenwood-logo-1500w.png 5x" class="style-scope app-banner">

            <h3 class="style-scope app-banner">The static site generator for your. . . <br class="style-scope app-banner"><span class="on style-scope app-banner"><!--?lit$1327782744$-->blog.</span></h3>

            <eve-button size="md" href="/getting-started/" style="/* stylelint-disable a11y/media-prefers-reduced-motion */ :host .btn {   display: inline-block;   border-radius: 10px;   font-size: 1.2rem;   padding: 0.75rem;   color: white;   background-color: #201e2e;   border: 1px solid white;   transition: 0.3s; }  :host .btn:hover, :host .btn:focus {   background-color: #425d58;   border: 1px solid white; }" class="style-scope app-banner"><!---->
    <style class="style-scope eve-button">
      :host .btn {     margin: 2px;     border: 1px solid var(--btn-border-color, var(--primary-color, green));     color: var(--btn-text-color, var(--primary-color, green));     background-color: var(--btn-background, var(--secondary-color, white) );     text-decoration:none;     position:relative;     display: inline-block;     border-radius: var(--btn-border-radius, 0px);   }      :host .btn:hover {       background-color: var(--btn-hover-background-color, var(--primary-color, green));       color: var(--btn-hover-text-color, var(--secondary-color, white));       border: 1px solid var(--btn-hover-border-color, var(--primary-color, green));     }   :host .btn-xs {     padding:5px;     font-size:12px;   }   :host .btn-sm {     padding:5px;     font-size:16px;   }   :host .btn-md {     padding:10px;     font-size:20px;   }   :host .btn-lg {     padding:15px;     font-size:25px;   }
    /* stylelint-disable a11y/media-prefers-reduced-motion */ :host .btn {   display: inline-block;   border-radius: 10px;   font-size: 1.2rem;   padding: 0.75rem;   color: white;   background-color: #201e2e;   border: 1px solid white;   transition: 0.3s; }  :host .btn:hover, :host .btn:focus {   background-color: #425d58;   border: 1px solid white; }</style>
      <!--?lit$1327782744$-->
          <a class="btn btn-md style-scope eve-button" href="/getting-started/" style="">
            Get Started
          </a>
          
    </eve-button>
          </div>
        
      </div>
    </eve-container>
      </div>
    <style class="style-scope app-banner">
      /* stylelint-disable a11y/media-prefers-reduced-motion */ :host .btn {   display: inline-block;   border-radius: 10px;   font-size: 1.2rem;   padding: 0.75rem;   color: white;   background-color: #201e2e;   border: 1px solid white;   transition: 0.3s; }  :host .btn:hover, :host .btn:focus {   background-color: #425d58;   border: 1px solid white; }
      @keyframes fadeOut {   from {     opacity: 1;   }    to {     opacity: 0;   } }  @keyframes fadeIn {   from {     opacity: 0;   }    to {     opacity: 1;   } }  :host .banner {     background-color: #fff;     min-height: 60vh;   }  :host .banner .content {       padding: 5vh 10px;       font-size: 1.7rem;       text-align: center;     }  :host .banner .content hr {         border-radius: 25px;         border-style: none;         height: 3px;         margin: 0 auto;         background-color: white;         border: 1px solid rgba(0, 0, 0, 0.6);         width: 160px;       }  :host .banner .content h1 {         font-size: 3.5rem;         color: #201e2e;       }  :host .banner .content h3 {         padding-top: 10px;         color: #201e2e;       }  :host .banner .content img {         width: 300px;         height: 300px;       }  @media screen and (prefers-reduced-motion: reduce) {       :host .banner span.off {         animation: none;       }          @media (prefers-reduced-motion) {       :host .banner span.off {           animation: 0       }         }     }  :host .banner span.off {       animation: 1s fadeOut ease-in-out;     }  @media screen and (prefers-reduced-motion: reduce) {       :host .banner span.on {         animation: none;       }     }  :host .banner span.on {       animation: 1s fadeIn linear;     }  @media (max-width: 980px) {     :host .banner {       min-height: 40vh;     }        :host .banner .content {         font-size: 1.5rem;       }          :host .banner .content h1 {           font-size: 3rem;         }          :host .banner .content img {           width: 250px;           height: 250px;         }   }  @media (max-width: 756px) {     :host .banner {       padding: 0;     }        :host .banner .content {         margin-top: 0;       }   }
    </style></app-banner>

      <div class="gwd-content-wrapper">

          <div class="gwd-page-template gwd-content">
            <div id="gwd-message-wrapper">
              <div class="message">
                <h2>Greenwood is a modern and performant static site generator for Web Component based development.</h2>

                <div class="min-card-container">
                  <div class="mini-card"><p>Prerendered, <a href="/about/how-it-works/" title="How It Works" target="_blank" rel="noopener noreferrer">even your Web Components</a></p></div>
                  <div class="mini-card"><p><a href="/docs/layouts/" title="Layout docs" target="_blank" rel="noopener noreferrer">Filesystem based routing</a></p></div>
                  <div class="mini-card"><p>A fast, unbundled, local development workflow</p></div>
                  <div class="mini-card"><p><a href="/about/goals/" title="Goals" target="_blank" rel="noopener noreferrer">Easy to get started with</a></p></div>
                  <div class="mini-card"><p>Extensible <a href="/plugins/" title="Plugins" target="_blank" rel="noopener noreferrer">plugin system</a></p></div>
                  <div class="mini-card"><p><a href="/docs/data/" title="Data docs" target="_blank" rel="noopener noreferrer">Content as data</a> with GraphQL</p></div>
                </div>
              </div>
            </div>

            <div class="quickstart">
              <h2>Quick Start Example</h2>
              <pre class="language-bash">                <code class="language-bash">
                  # with NodeJS already installed
                  # create a pages directory for your content
                  $ mkdir -p src/pages

                  # create an index.md file as your home page
                  $ echo "## hello world" &gt; src/pages/index.md

                  # run one of Greenwood's commands, and that's it!
                  $ npx @greenwood/cli develop
                </code>
              </pre>
              <p>For anyone new to Greenwood, we encourage you go through our <a href="/getting-started/">Getting Started</a> guide, or to get right to work, head on over to our <a href="/docs/">documentation</a>.</p>
            </div>

            <div class="cards">
              <app-card title="The Modern Web" img="../assets/webcomponents.svg"><!---->
      <!--?lit$1327782744$-->
        <div class="card-img-top style-scope app-card">
          <img loading="lazy" src="../assets/webcomponents.svg" alt="The Modern Web" class="style-scope app-card">
        </div>
      
      <!--?lit$1327782744$-->
        <h3 class="style-scope app-card"><!--?lit$1327782744$-->The Modern Web</h3>
      
      <p slot="cardcontent">Modern browsers, combined with recent advancements in web standards like <strong>Web Components</strong>, <strong>ES Modules</strong>, and <strong>CSS Custom Properties</strong>, bring a lot of native power and features to the web browsers we all use now.  With less need to put tools in front of your code, Greenwood makes completing your goals easier, faster, and less complicated.</p>
    <style class="style-scope app-card">
      :host {   position: relative;   display: flex;   flex-direction: column;   min-width: 0;   word-wrap: break-word;   background-color: #fff;   background-clip: initial;   text-align: center; }    :host slot {     text-align: left;     font-size: 1rem;   }    :host .card-img-top {     background-size: cover;     background-position-x: center;     background-position-y: center;   }    :host .card-img-top img {       width: 200px;       height: 200px;       max-width: 200px;     }
    </style></app-card>

              <app-card title="Ecosystem" img="../assets/nodejs.png"><!---->
      <!--?lit$1327782744$-->
        <div class="card-img-top style-scope app-card">
          <img loading="lazy" src="../assets/nodejs.png" alt="Ecosystem" class="style-scope app-card">
        </div>
      
      <!--?lit$1327782744$-->
        <h3 class="style-scope app-card"><!--?lit$1327782744$-->Ecosystem</h3>
      
      <p slot="cardcontent">While the web provides a lot out of the box, we want everyone to be able to reach for those additional packages we need that help us achieve our goal of building great things.  <strong>NodeJS</strong>, along with <strong>npm</strong>, provides a great developer experience and ecosystem to leverage when  building web projects.</p>
    <style class="style-scope app-card">
      :host {   position: relative;   display: flex;   flex-direction: column;   min-width: 0;   word-wrap: break-word;   background-color: #fff;   background-clip: initial;   text-align: center; }    :host slot {     text-align: left;     font-size: 1rem;   }    :host .card-img-top {     background-size: cover;     background-position-x: center;     background-position-y: center;   }    :host .card-img-top img {       width: 200px;       height: 200px;       max-width: 200px;     }
    </style></app-card>

              <app-card title="Keeping It Simple" img="../assets/simple.png"><!---->
      <!--?lit$1327782744$-->
        <div class="card-img-top style-scope app-card">
          <img loading="lazy" src="../assets/simple.png" alt="Keeping It Simple" class="style-scope app-card">
        </div>
      
      <!--?lit$1327782744$-->
        <h3 class="style-scope app-card"><!--?lit$1327782744$-->Keeping It Simple</h3>
      
      <p slot="cardcontent">Greenwood is on a mission to provide the best web development experience, to make sure content is easy to create, and that going live is a breeze.  Keeping things simple is a part of that mission, and while we levarge some open source tool to achieve all this, we intend to avoid the meta framework trend and aim keep to a lean(er) core over time.</p>
    <style class="style-scope app-card">
      :host {   position: relative;   display: flex;   flex-direction: column;   min-width: 0;   word-wrap: break-word;   background-color: #fff;   background-clip: initial;   text-align: center; }    :host slot {     text-align: left;     font-size: 1rem;   }    :host .card-img-top {     background-size: cover;     background-position-x: center;     background-position-y: center;   }    :host .card-img-top img {       width: 200px;       height: 200px;       max-width: 200px;     }
    </style></app-card>
            </div>

          </div>
      </div>

    </div>

  
      
      <app-footer><!---->
      <footer class="footer style-scope app-footer">
        <h4 class="style-scope app-footer">
          <a href="/" class="style-scope app-footer">Greenwood v<!--?lit$1327782744$-->0.13.0</a> <span class="separator style-scope app-footer"></span> <a href="https://www.netlify.com/" class="style-scope app-footer">This site is powered by Netlify</a>
        </h4>
      </footer>
    <style class="style-scope app-footer">
      :host {   grid-area: footer; }    :host .footer {     background-color: #192a27;     min-height: 30px;     padding-top: 10px;   }    :host .footer h4 {       width: 90%;       margin: 0 auto;       padding: 0;       text-align: center;     }    :host .footer a {       color: white;       text-decoration: none;     }    :host .footer span.separator {       color: white;     }
    </style></app-footer>
    </div>

  

327782744$--><!---->
                    <li class="style-scope app-header"><a href="/about/" title="Click to visit the About page" class="style-scope app-header"><!--?lit

    <div class="gwd-wrapper">
      <app-header><!---->
      <header class="header style-scope app-header">
        <eve-container fluid="" class="style-scope app-header"><!---->
      <style class="style-scope eve-container">
      <!---->@custom-media --screen-xs (max-width: 576px); @custom-media --screen-sm (min-width: 576px); @custom-media --screen-md (min-width: 768px); @custom-media --screen-lg (min-width: 992px); @custom-media --screen-xl (min-width: 1200px);  :host .container {     margin-right: auto;     margin-left: auto;     padding-left: 15px;     padding-right: 15px;   }  :host .container-fluid {     margin-right: auto;     margin-left: auto;     padding-left: 15px;     padding-right: 15px;   }  @media (--screen-xs) {     :host .container {       width: calc(100% - 30px);     }   }  @media (--screen-sm) {     :host .container {       width: 540px;     }   }  @media (--screen-md) {     :host .container {       width: 720px;     }   }  @media (--screen-lg) {     :host .container {       width: 960px;     }   }  @media (--screen-xl) {     :host .container {       width: 1140px;     }   }
      <!----></style>
      <div class="container-fluid style-scope eve-container">
        
    ...

      </router-outlet>
            
            
            <greenwood-route data-route="/about/community/" data-template="page" data-key="/_routes/about/community/index.html"></greenwood-route>
          

            <greenwood-route data-route="/about/features/" data-template="page" data-key="/_routes/about/features/index.html"></greenwood-route>
          

            <greenwood-route data-route="/about/goals/" data-template="page" data-key="/_routes/about/goals/index.html"></greenwood-route>
          

            <greenwood-route data-route="/about/how-it-works/" data-template="page" data-key="/_routes/about/how-it-works/index.html"></greenwood-route>
          

            <greenwood-route data-route="/about/" data-template="page" data-key="/_routes/about/index.html"></greenwood-route>
          

            <greenwood-route data-route="/docs/component-model/" data-template="page" data-key="/_routes/docs/component-model/index.html"></greenwood-route>
          

            <greenwood-route data-route="/docs/configuration/" data-template="page" data-key="/_routes/docs/configuration/index.html"></greenwood-route>
          

            <greenwood-route data-route="/docs/css-and-images/" data-template="page" data-key="/_routes/docs/css-and-images/index.html"></greenwood-route>
          

            <greenwood-route data-route="/docs/data/" data-template="page" data-key="/_routes/docs/data/index.html"></greenwood-route>
          

            <greenwood-route data-route="/docs/front-matter/" data-template="page" data-key="/_routes/docs/front-matter/index.html"></greenwood-route>
          

            <greenwood-route data-route="/docs/" data-template="page" data-key="/_routes/docs/index.html"></greenwood-route>
          

            <greenwood-route data-route="/docs/layouts/" data-template="page" data-key="/_routes/docs/layouts/index.html"></greenwood-route>
          

            <greenwood-route data-route="/docs/markdown/" data-template="page" data-key="/_routes/docs/markdown/index.html"></greenwood-route>
          

            <greenwood-route data-route="/docs/menus/" data-template="page" data-key="/_routes/docs/menus/index.html"></greenwood-route>
          

            <greenwood-route data-route="/docs/tech-stack/" data-template="page" data-key="/_routes/docs/tech-stack/index.html"></greenwood-route>
          

            <greenwood-route data-route="/getting-started/branding/" data-template="page" data-key="/_routes/getting-started/branding/index.html"></greenwood-route>
          

            <greenwood-route data-route="/getting-started/build-and-deploy/" data-template="page" data-key="/_routes/getting-started/build-and-deploy/index.html"></greenwood-route>
          

            <greenwood-route data-route="/getting-started/creating-content/" data-template="page" data-key="/_routes/getting-started/creating-content/index.html"></greenwood-route>
          

            <greenwood-route data-route="/getting-started/" data-template="page" data-key="/_routes/getting-started/index.html"></greenwood-route>
          

            <greenwood-route data-route="/getting-started/key-concepts/" data-template="page" data-key="/_routes/getting-started/key-concepts/index.html"></greenwood-route>
          

            <greenwood-route data-route="/getting-started/next-steps/" data-template="page" data-key="/_routes/getting-started/next-steps/index.html"></greenwood-route>
          

            <greenwood-route data-route="/getting-started/project-setup/" data-template="page" data-key="/_routes/getting-started/project-setup/index.html"></greenwood-route>
          

            <greenwood-route data-route="/getting-started/quick-start/" data-template="page" data-key="/_routes/getting-started/quick-start/index.html"></greenwood-route>
          

            <greenwood-route data-route="/guides/cloudflare-workers-deployment/" data-template="page" data-key="/_routes/guides/cloudflare-workers-deployment/index.html"></greenwood-route>
          

            <greenwood-route data-route="/guides/firebase/" data-template="page" data-key="/_routes/guides/firebase/index.html"></greenwood-route>
          

            <greenwood-route data-route="/guides/" data-template="page" data-key="/_routes/guides/index.html"></greenwood-route>
          

            <greenwood-route data-route="/guides/netlify-cms/" data-template="page" data-key="/_routes/guides/netlify-cms/index.html"></greenwood-route>
          

            <greenwood-route data-route="/guides/netlify-deploy/" data-template="page" data-key="/_routes/guides/netlify-deploy/index.html"></greenwood-route>
          

            <greenwood-route data-route="/guides/now/" data-template="page" data-key="/_routes/guides/now/index.html"></greenwood-route>
          

            <greenwood-route data-route="/guides/s3-cloudfront/" data-template="page" data-key="/_routes/guides/s3-cloudfront/index.html"></greenwood-route>
          

            <greenwood-route data-route="/" data-template="/" data-key="/_routes/index.html"></greenwood-route>
          

            <greenwood-route data-route="/plugins/custom-plugins/" data-template="page" data-key="/_routes/plugins/custom-plugins/index.html"></greenwood-route>
          

            <greenwood-route data-route="/plugins/" data-template="page" data-key="/_routes/plugins/index.html"></greenwood-route>
          

            <greenwood-route data-route="/plugins/resource/" data-template="page" data-key="/_routes/plugins/resource/index.html"></greenwood-route>
          

            <greenwood-route data-route="/plugins/rollup/" data-template="page" data-key="/_routes/plugins/rollup/index.html"></greenwood-route>
          

            <greenwood-route data-route="/plugins/server/" data-template="page" data-key="/_routes/plugins/server/index.html"></greenwood-route>
          
          </body>
        </html>

(if you view the source of the upgrade branch, you'll the HTML goes on for miles....

So a couple thoughts to address this:

  1. Upgrade our version of puppeteer since ours is old and probably doesn't support Declarivate Shadow DOM, something also captured as part of routine maintenance and semver major upgrades of key dependencies #630
  2. Also on our Roadmap but as a more robust solution, is implement true SSR capabilities to HTMLElement (and LitElement via a plugin) and give a more programmatic option that just pre-rendering with Puppeteer
  3. At the risk of overly testing our tools, I'm not sure if the fact that the build didn't break in upgrade website to lit@2 #611 should be some sort of sign we to do some sort of smoke testing / coverage for puppeteer?
@thescientist13 thescientist13 added bug Something isn't working CLI SSR labels Jul 29, 2021
@thescientist13 thescientist13 added this to the 1.0 milestone Jul 29, 2021
@thescientist13 thescientist13 self-assigned this Jul 29, 2021
@thescientist13
Copy link
Member Author

thescientist13 commented Jul 29, 2021

Not sure this warrants a P0 just yet as Lit@2 is still in RC, but I think certainly we should be motivated to solve by the time it does, but their roadmap is still unclear and in hand means we can support Declarative Shadow DOM in general.

@thescientist13
Copy link
Member Author

Some initial experiments with upgrading puppeteer - #699

@thescientist13
Copy link
Member Author

thescientist13 commented Sep 7, 2021

Should also test new polyfills for declarative shadow dom
https://github.com/webcomponents/template-shadowroot
https://github.com/webcomponents/polyfills

@thescientist13
Copy link
Member Author

thescientist13 commented Sep 7, 2021

So it may be down to how Lit now renders web components / Shadow DOM now and what impact it may have on how styles / Shadow DOM gets rendered out now through puppeteer? I know they're SSR implementation has now moved to rendering out to Declarative Shadow DOM, e.g.

<template shadowroot="open">
  ...
<template>

For example, I now see a difference in how the serialized HTML is coming out. Before, we would see something like this with the custom element tag name as the CSS selector

<!-- Shady DOM styles for app-header --><style scope="app-header">app-header .header.app-header {
  background-color: #192a27;     min-height: 30px;     padding: 10px;     font-size: 1.2rem;
}

app-header .header.app-header a.app-header {
  color: white;       text-decoration: none;
}

app-header .header.app-header .project-name.app-header {
  margin: -2px 0 auto;       padding: 0;       padding-top: 4px;       display: inline-block;       color: #201e2e;       font-weight: bold;
}

app-header .header.app-header .head-wrap.app-header {
  display: flex;       align-items: center;       flex-wrap: wrap;       justify-content: space-between;
}

@media (max-width: 768px) {
app-header .header.app-header .head-wrap.app-header {
  flex-direction: column;         text-align: center
}

Screen Shot 2021-09-07 at 3 50 55 PM

Now, we see it like this, using :host instead

     </div>
    </eve-container>
      </header>
    <style class="style-scope app-header">
      :host .header {     background-color: #192a27;     min-height: 30px;     padding: 10px;     font-size: 1.2rem;   }      :host .header a {       color: white;       text-decoration: none;     }      :host .header .project-name {       margin: -2px 0 auto;       padding: 0;       padding-top: 4px;       display: inline-block;       color: #201e2e;       font-weight: bold;     }      :host .header .head-wrap {       display: flex;       align-items: center;       flex-wrap: wrap;       justify-content: space-between;     }      @media (max-width: 768px) {      :host .header .head-wrap {         flex-direction: column;         text-align: center     }       }      :host .header nav {       justify-items: left;       width: 55%;     }      :host .header nav ul {         padding: 0;         margin: 0;         list-style: none;         text-align: center;       }      :host .header nav ul li {           margin: 0;           color: white;           display: inline-block;           padding: 10px;         }      :host .header nav ul li:hover,           :host .header nav ul li:focus {             color: #f9e7ca;           }      :host .header nav ul li:hover a, :host .header nav ul li:focus a {               color: green;             }      @media (max-width: 768px) {      :host .header nav {         width: 100%     }       }      :host .header .brand {       justify-items: left;       padding: 10px;     }      :host .header .brand img {         float: left;         height: 30px;         width: 30px;         margin-right: 0.5rem;       }      :host .header .social {       margin-left: auto;       text-align: right;     }      :host .header .social img {         width: 84px;         height: 20px;       } 
    </style></app-header>

Screen Shot 2021-09-07 at 3 56 16 PM

Normally this probably wouldn't be an issue BUT combined with the strict optimization setting, which strips out the runtime JavaScript, we get no styles because :host is meaningless outside of a Shadow DOM, which these styles are not in.

Opened a PR to follow along with the WIP - #719

My guess it is a Lit thing since upgrading to Puppeteer against original Lit didn't cause any issues from what I could tell in #699


Found some interesting links to track though to see if we can get the old output we had, otherwise might have to warn about compatibility issues when using puppeteer? 🥺

@thescientist13
Copy link
Member Author

thescientist13 commented Sep 14, 2021

OK, so as suspected, if I manually remove :host from the <style> block, things work. 👍

<!-- before -->
<style class="style-scope app-header">
  :host .header {     background-color: #192a27;     min-height: 30px;     padding: 10px;     font-size: 1.2rem;   }      :host .header a {       color: white;       text-decoration: none;     }      :host .header .project-name {       margin: -2px 0 auto;       padding: 0;       padding-top: 4px;       display: inline-block;       color: #201e2e;       font-weight: bold;     }      :host .header .head-wrap {       display: flex;       align-items: center;       flex-wrap: wrap;       justify-content: space-between;     }      @media (max-width: 768px) {      :host .header .head-wrap {         flex-direction: column;         text-align: center     }       }      :host .header nav {       justify-items: left;       width: 55%;     }      :host .header nav ul {         padding: 0;         margin: 0;         list-style: none;         text-align: center;       }      :host .header nav ul li {           margin: 0;           color: white;           display: inline-block;           padding: 10px;         }      :host .header nav ul li:hover,           :host .header nav ul li:focus {             color: #f9e7ca;           }      :host .header nav ul li:hover a, :host .header nav ul li:focus a {               color: green;             }      @media (max-width: 768px) {      :host .header nav {         width: 100%     }       }      :host .header .brand {       justify-items: left;       padding: 10px;     }      :host .header .brand img {         float: left;         height: 30px;         width: 30px;         margin-right: 0.5rem;       }      :host .header .social {       margin-left: auto;       text-align: right;     }      :host .header .social img {         width: 84px;         height: 20px;       } 
</style>

<!-- after -->
 <style class="style-scope app-header">
     .header {     background-color: #192a27;     min-height: 30px;     padding: 10px;     font-size: 1.2rem;   }      .header a {       color: white;       text-decoration: none;     }      .header .project-name {       margin: -2px 0 auto;       padding: 0;       padding-top: 4px;       display: inline-block;       color: #201e2e;       font-weight: bold;     }      .header .head-wrap {       display: flex;       align-items: center;       flex-wrap: wrap;       justify-content: space-between;     }      @media (max-width: 768px) {      .header .head-wrap {         flex-direction: column;         text-align: center     }       }      .header nav {       justify-items: left;       width: 55%;     }      .header nav ul {         padding: 0;         margin: 0;         list-style: none;         text-align: center;       }      .header nav ul li {           margin: 0;           color: white;           display: inline-block;           padding: 10px;         }      .header nav ul li:hover,           .header nav ul li:focus {             color: #f9e7ca;           }      .header nav ul li:hover a, .header nav ul li:focus a {               color: green;             }      @media (max-width: 768px) {      .header nav {         width: 100%     }       }      .header .brand {       justify-items: left;       padding: 10px;     }      .header .brand img {         float: left;         height: 30px;         width: 30px;         margin-right: 0.5rem;       }      .header .social {       margin-left: auto;       text-align: right;     }      .header .social img {         width: 84px;         height: 20px;       } 
</style>

Screen Shot 2021-09-14 at 11 35 11 AM


So it seems that if I can get those Shady DOM styles back, we should be able to keep things as is, but otherwise, it looks like a little manual intervention may be needed on the Greenwood side.

The only challenge / risk I forsee is that not every instance of :host will need this find / replace logic, so I'm not sure what the repercussions are removing it for everything and if this would interfere into how Lit or HTMLElement would faux-hydrate themselves.

@thescientist13
Copy link
Member Author

thescientist13 commented Sep 14, 2021

LOL, just had to RTFM I guess 🤦 🤣

PR is up and now Shady DOM styles are back!

@thescientist13 thescientist13 changed the title Declarative Shadow DOM (Lit@2) results in broken component rendering and styles when pre-rendering with puppeteer strict optimization w/ Lit@2 results in broken component rendering and styles when pre-rendering with puppeteer (Shady DOMm) Sep 14, 2021
@thescientist13 thescientist13 changed the title strict optimization w/ Lit@2 results in broken component rendering and styles when pre-rendering with puppeteer (Shady DOMm) strict optimization w/ Lit@2 results in broken component rendering and styles when pre-rendering with puppeteer (Shady DOM) Sep 14, 2021
@thescientist13 thescientist13 changed the title strict optimization w/ Lit@2 results in broken component rendering and styles when pre-rendering with puppeteer (Shady DOM) Lit@2 results in broken component rendering and styles when pre-rendering with puppeteer (Shady DOM) Sep 14, 2021
@thescientist13 thescientist13 changed the title Lit@2 results in broken component rendering and styles when pre-rendering with puppeteer (Shady DOM) Lit@2 not providing Shady DOM styles styles when pre-rendering with puppeteer Sep 14, 2021
@thescientist13 thescientist13 linked a pull request Sep 22, 2021 that will close this issue
2 tasks
@thescientist13 thescientist13 changed the title Lit@2 not providing Shady DOM styles styles when pre-rendering with puppeteer Lit@2 Shady DOM styles not present when pre-rendering with puppeteer Sep 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
1 participant