Skip to content

Commit

Permalink
v0.26.0 release blog post (#963)
Browse files Browse the repository at this point in the history
* first draft of v0.26.0 blog post

* quick grammar fix

* remove extraneous character

* misc edits and revisions
  • Loading branch information
thescientist13 committed Jul 27, 2022
1 parent bb7d662 commit 3854a53
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 0 deletions.
Binary file added www/assets/blog-images/wcc-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions www/pages/blog/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ template: blog

# News and Announcements

- [Release: v0.26.0](/blog/release/v0-26-0/) 📝
- [Release: v0.24.0](/blog/release/v0-24-0/) 📝
- [State of Greenwood (2022)](/blog/state-of-greenwood-2022/) 📣
- [Release: v0.23.0](/blog/release/v0-23-0/) 📝
Expand Down
210 changes: 210 additions & 0 deletions www/pages/blog/release/v0-26-0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
---
label: 'blog'
title: v0.26.0 Release
template: blog
---

# Greenwood v0.26.0

**Published: July 26, 2022**

## What's New

After a lot of hard work, the Greenwood team is eager to share our first round of enhancements related to our [SSR work](/blog/release/v0-24-0/). By fully leaning into Web Components as a standard API for server rendered pages, we have finally realized something we've been chasing since the early days of the project; all made possible through a new library we've started developing called [**Web Components Compiler (WCC)**](https://github.com/ProjectEvergreen/wcc)! 📣

<style>
img {
width: 60%!important;
margin-left: 20%;
}
</style>

![WCC logo](/assets/blog-images/wcc-logo.png)

### Custom Elements as Pages

The most significant change in this release is how Greenwood handles server rendering by default. Instead of spinning up a (headless) browser with Puppeteer, WCC now provides the ability to deliver on what we think is a really nice and familiar developer experience for authoring server rendered content. We think custom elements fit right at home in providing a consistent and standards based solution for authoring pages, just as easily as they do for components.

Here is an example of what authoring an SSR page in Greenwood looks like now if using the new `export default` API.
```js
// src/pages/artists.js
import fetch from 'node-fetch';
import '../components/card.js';

export default class ArtistsPage extends HTMLElement {
async connectedCallback() {
const artists = await fetch('https://.../api/artists').then(resp => resp.json());
const html = artists.map(artist => {
const { name, imageUrl } = artist;

return `
<wc-card>
<h2 slot="title">${name}</h2>
<img slot="image" src="${imageUrl}" alt="Picture of ${name}"/>
</wc-card>
`;
}).join('');

this.innerHTML = `
<h1>List of Artists: ${artists.length}</h1>
${html}
`;
}
}
```

> **Note**: In this example, Greenwood will _not_ ship any JS for this page. All the HTML is extracted at build / request time from the custom element. 💯
Since WCC is un-opinionated in how you author your custom elements, you will notice from the above snippet that there is no usage of Shadow DOM. This is intentional as this page content is _intended for the Light DOM_. The goal here is to allow users to opt-in as needed where it makes sense, because not everything needs the tight encapsulation of a Shadow Root.

However, the `<wc-card></wc-card>` totally _can_ opt-in to [(Declarative) Shadow DOM](https://web.dev/declarative-shadow-dom/) as you can see through its component definition, and its usage of `<slot>`s. It all works the same!
```js
const template = document.createElement('template');

template.innerHTML = `
<style>
:host {
display: block;
width: 80%;
margin: 50px auto!important;
text-align: center;
}
[name="title"] {
color: red;
}
::slotted(img) {
max-width: 500px;
}
hr {
border-top: 1px solid var(--color-accent);
}
</style>
<div class="card">
<slot name="title">My default title</slot>
<slot name="image"></slot>
</div>
<hr/>
`;

export default class Card extends HTMLElement {
connectedCallback() {
if (!this.shadowRoot) {
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}
}

customElements.define('wc-card', Card);
```

### WCC

In keeping with the spirit of Project Evergreen, the team wanted to keep things as close to the vest as possible. Although Greenwood does support [**Lit** as an SSR solution](https://github.com/ProjectEvergreen/greenwood/tree/master/packages/plugin-renderer-lit), we wanted to make sure that it could be just as easy to author native `HTMLElement` custom elements, and refine that developer experience for the benefit of the community.

For those curious, let's take a quick peek under the hood to see how it works.

1. Write a Web Component
```js
const template = document.createElement('template');

template.innerHTML = `
<style>
.footer {
color: white;
background-color: #192a27;
}
</style>
<footer class="footer">
<h4>My Blog &copy; ${new Date().getFullYear()}</h4>
</footer>
`;

class Footer extends HTMLElement {
connectedCallback() {
if (!this.shadowRoot) {
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}
}

export default Footer;

customElements.define('wcc-footer', Footer);
```
1. Run it through the compiler
```js
import { renderToString } from 'wc-compiler';
const { html } = await renderToString(new URL('./path/to/component.js', import.meta.url));
```
1. Get HTML!
```html
<wcc-footer>
<template shadowroot="open">
<style>
.footer {
color: white;
background-color: #192a27;
}
</style>
<footer class="footer">
<h4>My Blog &copy; 2022</h4>
</footer>
</template>
</wcc-footer>
```

Web Components Compiler is designed to make the writing and rendering of native web components as easy as possible, and has [serverless and the edge in mind](https://github.com/thescientist13/web-components-at-the-edge) as first party runtimes, which we plan to support in Greenwood [very soon](https://github.com/ProjectEvergreen/greenwood/issues/953). It is an opportunity to explore the web and ideate on shared goals and objectives. It also has no opinions on Light vs. Shadow DOM, recognizing that not one size fits all.

WCC also has no opinion on framework. We've even made [a plugin for **11ty**](https://github.com/ProjectEvergreen/eleventy-plugin-wcc) you can try! 🎈
And so now has come the time when Greenwood can transition off of Puppeteer and continue to live up to its ideal of becoming leaner over time and staying true to being _your workbench for the web_.
### Puppeteer Plugin
> 🛑 **This is a breaking change** 🛑
OK, so by now with all this talk of WCC and internalized SSR support for web components, we should talk about Puppeteer. One thing the Greenwood team recognizes is that there are some things having access to an entire (headless) browser can provide, and in some cases, [certain features](https://github.com/ProjectEvergreen/greenwood/tree/master/packages/plugin-graphql#caveats) still depend on it [(for now)](https://github.com/ProjectEvergreen/greenwood/issues/952).
So although WCC is now the default for SSR, Puppeteer is still available as a plugin that can be installed after you make the upgrade to `v0.26.0`. The upgrade should be quick and work the same as it did before. Just follow these steps.
1. Install the Puppeteer renderer plugin
```shell
$ npm install @greenwood/plugin-renderer-puppeteer --save-dev
```
1. Add the plugin to your _greenwood.config.js_. You can also remove `prerender: true`.
```js
import { greenwoodPluginRendererPuppeteer } from '@greenwood/plugin-renderer-puppeteer';
export default {
plugins: [
...greenwoodPluginRendererPuppeteer()
]
}
```
1. You can also delete the **puppeteer** package from your _package.json_.
That's it!


## Learn More

That was a lot of info and a lot of new things to look forward to when building your next Greenwood project. We're very eager to continue exploring where WCC can go to really continue to enhance the authoring experience for native custom elements, and what we can be accomplished with Greenwood + WCC running at the edge!
For more information, check out these links:
- [SSR docs](/docs/server-rendering/) including the new `export default` API
- Check out the [WCC repo](https://github.com/ProjectEvergreen/wcc) and [website](https://merry-caramel-524e61.netlify.app/)
- New package for the [Puppeteer renderer plugin](https://github.com/ProjectEvergreen/greenwood/tree/master/packages/plugin-renderer-puppeteer)
- See the [release notes in GitHub](https://github.com/ProjectEvergreen/greenwood/releases/tag/v0.26.0)
Thanks for reading!

0 comments on commit 3854a53

Please sign in to comment.