
React Static Site - tambourine_man
http://braddenver.com/blog/2015/react-static-site.html
======
asolove
I am using static-site-generator-webpack-plugin [0] on a client project now
and it has been fantastic. I have one json file full of all the data of the
site and then a bunch of components that render it in various ways. I've got
translations in several languages plus the components can use React-Intl to
get text, dates, etc. in the right format for the locale.

The experience has been fantastic compared to other static site generators
(very limited control over display of content) or CMSes (too indirect for what
is basically simple logic, especially around internationalization).

It was a bit fiddly getting everything set up so that React, React Router,
React Intl, and Static Site Generator all played nicely together. But after
about a day of banging my head on that, it's just worked ever since and been a
dream.

If I could ask for one improvement: right now the build first runs the code
through Babel and then runs that through WebPack. Problem is, if parts of the
Babel build fail, there's no error reporting, and instead I get a WebPack-
stage error about some file not being available. I then have to manually run
the file through Babel to see that there's a simple syntax error.

[0] [https://github.com/markdalgleish/static-site-generator-
webpa...](https://github.com/markdalgleish/static-site-generator-webpack-
plugin)

~~~
TN1ck
You can use babel-eslint [0] and the eslint-loader [1] to catch all errors
babel might have.

[0] [https://github.com/babel/babel-eslint](https://github.com/babel/babel-
eslint)

[1] [https://github.com/MoOx/eslint-loader](https://github.com/MoOx/eslint-
loader)

~~~
asolove
Awesome, thanks!

------
mambodog
The React DnD docs/examples site is rendered in a similar manner:

[https://github.com/gaearon/react-
dnd/blob/master/scripts/bui...](https://github.com/gaearon/react-
dnd/blob/master/scripts/buildSiteIndexPages.sh)

------
zastavka
This is a pretty neat approach to building a static site, and it reminds me
that a couple months ago I was experimenting with building a static site
generator in Clojure. Which makes me think – is there any reason something
like this couldn't be done with Clojurescript and Reagent? I've been itching
to try out both of those but haven't come up with a good project for it.

The hard part might be routing, since there doesn't seem to be a robust
solution for doing that in Reagent yet. I found
[https://github.com/ghedamat/reagent-react-
router](https://github.com/ghedamat/reagent-react-router) but it hasn't been
updated in months and the author calls it "very very alpha."

~~~
enoch_r
I've been using reagent with re-frame[1]. Routing just uses goog.events and
goog.history to listen for navigation events, secretary[1] to define routes,
which update the state rendered by your components. The code is here:
[https://github.com/Day8/re-frame-
template/blob/master/src/le...](https://github.com/Day8/re-frame-
template/blob/master/src/leiningen/new/re_frame/src/cljs/routes.cljs)

[1] [https://github.com/Day8/re-frame](https://github.com/Day8/re-frame) and
[https://github.com/Day8/re-frame-template](https://github.com/Day8/re-frame-
template)

You'll have to do `lein new re-frame <project> +routes` to pull in the routing
template.

[2] [https://github.com/gf3/secretary](https://github.com/gf3/secretary)

~~~
zastavka
Thanks for this! re-frame's probably little heavyweight for what I'd want to
do, but secretary looks rad, so at the very least I'll look into that.

------
jlu
Also have a look at metalsmith-react:

[https://github.com/coodoo/metalsmith-
reactjs](https://github.com/coodoo/metalsmith-reactjs)

------
colinramsay
Facebook does this with the React Native website I believe:

[https://github.com/facebook/react-
native/tree/master/website...](https://github.com/facebook/react-
native/tree/master/website/server)

------
vkjv
What is the argument for going _completely_ static? Static as in not using
React on the client, not as in static files.

It seems (to me), that it would be useful--in addition to the static html--
load React on the client and from that point navigate with push state and
small static (JSON?) files. It might perform better if your blog has a lot
more interactivity. Although, here I can definitely see that as being fluff.

~~~
dugmartin
I played around with building something similar. The problem becomes that you
have to send down twice the amount of data for the page - the statically
rendered html generated from your data and then the data itself so that when
the React components mount their props/state match the statically generated
html.

~~~
adregan
A few of the flux implementations have the concept of "rehydrating" state
(serializing and deserializing the stores), which does allow the client side
to reuse the data and keeps the component from refetching the data.

A useful pattern I discovered was fetching just what is necessary to render
the page on the server. Then pass the state to the window object through a
script tag and recover the data on the client side and rehydrate. Any
additional data (or potentially slow returning), I fetch client side via
`componentDidMount` [0] which isn't called on the server. This way, I can get
a loading screen up as quickly as possible with a few elements custom to the
user.

I should note that even thought the flux library I was using, flummox [1],
works great for this, I can't recommend it as in the month and a half I was
working on my project they've decided to quit and recommend a different
library, so I'm not sure what to recommend now (the frustration I feel over
this quick turnaround is an entirely separate topic, though).

0: [https://facebook.github.io/react/docs/component-
specs.html#m...](https://facebook.github.io/react/docs/component-
specs.html#mounting-componentdidmount)

1: [http://acdlite.github.io/flummox](http://acdlite.github.io/flummox)

2: [https://github.com/acdlite/flummox#40-will-likely-be-the-
las...](https://github.com/acdlite/flummox#40-will-likely-be-the-last-major-
release-use-redux-instead-its-really-great)

~~~
betenoire
the newly recommended library, redux, is great. Flummox was great too, but
redux is better, I recommend giving it a shot if you haven't.

To the original point, you are still sending the data twice, once in rendered
html, and once in that state that gets rehydrated.

~~~
Ambroos
Depending on the kind of content t you have, that's hardly an issue. I've
built a big site like this, and gzip does an extremely good job at filtering
out duplicate data. Check the source of
[http://viva.vlaanderen/](http://viva.vlaanderen/)

~~~
betenoire
when you view the source of your page, you see that very little of the
dehydrated state is used to build your initial markup.

The entire rendered source is 142K. I isolated the actual markup, and it
weighs in at 31K.

In other words, your dehydrated state is 4x bigger than your html rendering.
And that's not including your 750K main.js file that also gets downloaded.

That's almost 1MB of downloads (not including images and stylesheets) just to
"app-ify" your 31K of markup. I tend to agree, it's not a problem. Or perhaps,
it's not one of the biggest problems. But it's not "hardly an issue" either.

------
alinspired
[http://docpad.org/](http://docpad.org/) seems to be an alternative. It worked
great as a static blog generator with multitude of npm plugings and tools to
choose

------
digitalzombie
I use Octopress, it's basically a wrapper around Jekyll.

[http://octopress.org/](http://octopress.org/)

You just have to memorize a few command to publish stuff.

Also of course, know Markdown.

~~~
danesparza
I believe you have to install Ruby as well -- don't you?

~~~
digitalzombie
I'm not sure if you're joking but... it's a given.

Likewise with PHP and wordpress or Node.js and Ghost.

~~~
danesparza
It's not a given, and I wasn't joking.

I've used Jeykl and Octopress and a few others. I dislike having to install
random libraries just to get simple blog to render properly.

Go-lang built tools (like the free and excellent Hugo -
[https://gohugo.io/](https://gohugo.io/)) are single binaries. Just get the
one that works on your platform.

------
onion2k
_I don’t feel the need to join the WordPress cult_

Blogging 101: If you write petty, snarky comments about millions of other
developers, people will focus on those rather than the content of your post.

------
TeeWEE
I like the idea of React. However, Mixing HTML in your javascript is a very
bad thing. You are mixing presentation with logic, and i always try to prevent
that. Keep your logic away from your templates. I think its doable with react,
but most people dont do it... Can somebody explain me why?

    
    
      +    return (
      +      <html>
      +        <head>
      +          <title>{this.props.title}</title>
      +        </head>
      +        <body>
      +          {this.props.children}
      +          {script}
      +        </body>
      +      </html>
      +    );
    
    

[https://github.com/jlongster/blog/blob/master/src/components...](https://github.com/jlongster/blog/blob/master/src/components/header.js)

~~~
bryanlarsen
React is a view layer, so a good React component is all presentation and
doesn't contain any business logic. The only logic in a React component is
presentation logic, which belongs together with your presentation structure
and your presentation style, IMO.

~~~
TeeWEE
I like this answer, however, its still not sufficient. Because you dont want
to mix the "structure" of your UI with the behaviour of it. But in very
dynamic apps behaviour = structure. So in that case React makes sense.

However, i dove into web components with Polymer, and it seems that this is
the "official" direction of components in the future web... It also doesnt try
to mix HTML with JavaScript. In fact in the future there will be more
langauges than javascript since there will be a bytecode for the browser.
Having your app written in React poses a real problem when you want to switch
your logic to a different programming language.

So isnt the Web Components solution much better?

It seems that React and Web Components can be combined:
[https://github.com/Wildhoney/Maple.js](https://github.com/Wildhoney/Maple.js)

~~~
abritinthebay
> you dont want to mix the "structure" of your UI with the behaviour of it.

And you don't have to with React. But you can do this kind of mess with any
templating langauge - it's not a React issue, it's a bad programming issue.

> Having your app written in React poses a real problem when you want to
> switch your logic to a different programming language.

It really shouldn't. It's a View layer and the JSX part will be (practically)
HTML still so it'll be _really easy_ to port. The rest of the view logic would
have to be ported no-matter what you use to decorate it.

So this isn't really an objection.

