San Blas Documentation

San Blas isn't a library you install. Instead, it's a template repo.

View the repo on GitHub and when you're ready, click the green Use this template button.

Getting started

Install dependencies: yarn or npm install. The rest of these docs assume you're using Yarn, but the npm equivalents should be fine too.

San Blas' package.json comes with 3 scripts:

  • yarn storybook starts Storybook at http://localhost:9000
  • yarn start builds the site in development mode and serves it at http://localhost:5000
  • yarn build builds the site in production mode into the output directory

Entrypoints

The 2 files in the entrypoints directory will be bundled by Webpack:

prerender.js

This entrypoint's default export is a function that builds your site's HTML files.

A basic prerender function that renders a page for each React component in the pages directory is provided, but you can prerender your HTML pages however you like!

There's a vast ecosystem of existing tools like Gulp, Metalsmith & Hexo for rendering HTML, parsing Markdown, generating RSS feeds, etc, that you can take advantage of alongside modern staples like React, Webpack & Babel.

client.js

This entrypoint defines the JS bundle that will be loaded by a <script> tag on your pages. Use it to enhance your prerendered HTML with client-side JS.

The provided client entrypoint does a few things by default:

Rehydrate Fela styles

If you use Fela in your client bundle (including in any components), you need to rehydrate fela-dom's cache from prerendered styles.

Import and rehydrate prerendered San Blas withIsland() components

If you're using withIsland() to render isomorphic React components, you need to ensure those components are included in the client bundle so they can be used to hydrate the prerendered islands.

withIsland()

The withIsland() higher order component provides a simple way to prerender a React component and have the client JS bundle automatically hydrate it with the same props it was prerendered with.

withIsland(Component, { islandTag, islandString, hydrateAs })

Returns a React component that will render the supplied component with the supplied props, wrapped in an element with special data- attributes (see 'How it works' below).

Example

See the example page

Parameters

Component (required)

Any React component whose props can be serialised with JSON.stringify.

options.islandTag

Type: String Default: 'div'

Name of the HTML tag the component should be wrapped with.

options.islandProps

Type: Object Default: {}

Props (i.e. HTML attributes) to apply to the wrapper element.

options.hydrateAs

Type: String Default: displayName or name of the passed Component

Should match a key in componentMap in entrypoints/client.js

How it works

Say you have an isomorphic Nav component that accepts a single links prop:

const Nav = ({ links = [] }) => (
  <nav>
    {links.map((link) => (
      <a href={link} onClick={() => alert('🏝')}>{link}</a>
    ))}
  </nav>
)

When decorated with withIsland() this component will prerender some HTML like this:

<div
  data-sanblas-hydrate-as='Nav'
  data-sanblas-hydrate-with='{\"links\":[\"home\",\"about\"]}'
>
  <nav>
    <a href='home'>home</a>
    <a href='about'>about</a>
  </nav>
</div>

The client bundle will find that HTML and hydrate it.

Recipes

🚧 More coming soon!

  • Use existing blog frameworks:
    • Metalsmith
  • Alternative component library:
    • Preact
  • Alternative CSS approaches:
    • CSS Modules
    • Styled Components
    • Vanilla CSS
  • No client JS at all (you are my hero 😍)
  • Live reloading dev server