# Creating websites with shadow-cljs + gatsby or next.js

**URL:** https://clojureverse.org/t/creating-websites-with-shadow-cljs-gatsby-or-next-js/2912
**Category:** shadow-cljs
**Created:** [September 24, 2018, 6:29pm UTC](https://clojureverse.org/t/creating-websites-with-shadow-cljs-gatsby-or-next-js/2912 "2018-09-24T18:29:53Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![thheller](https://clojureverse.org/user_avatar/clojureverse.org/thheller/32/534_2.png) [@thheller](https://clojureverse.org/u/thheller)
#### Post date: [September 24, 2018, 6:29pm UTC](https://clojureverse.org/t/creating-websites-with-shadow-cljs-gatsby-or-next-js/2912/1 "2018-09-24T18:29:53Z")

</div>

> Gatsby.js is a static PWA (Progressive Web App) generator.

[gatsby](https://www.gatsbyjs.org/) is a pretty popular JS tool to build websites using React. The question whether its possible to use it with CLJS has come up a few times in the past and I got curious in how shadow-cljs could help with that.

For anyone interested I created a [sample repo](https://github.com/thheller/gatsby-cljs) that recreates parts of their default [starter template](https://github.com/gatsbyjs/gatsby-starter-default).

The basic idea is that you create normal CLJS `defn` per “page” and slap some [metadata](https://github.com/thheller/gatsby-cljs/blob/master/src/main/demo/gatsby.cljs#L44-L62) on it. The metadata will be used by a shadow-cljs [build-hook](https://github.com/thheller/gatsby-cljs/blob/master/src/main/shadow/gatsby.clj) to create the `src/pages` files that gatsby will look for. The files basically just map to the the CLJS defn to the data that gatsby expects. All code is written in CLJS and no JS code is used. The `site` directory was generated by `gatsby new` and the `shadow-cljs` build will output the relevant files to `site/src`.

I would not recommend that anyone actually builds a full site using this since it is a pretty bad fit IMHO. `gatsby` has certain assumptions that don’t map well to CLJS. What doesn’t work at all is the use of their `StaticQuery` component since they process the actual JS AST to extract the queries at compile time. Since it doesn’t understand the code generated by CLJS it just fails to extract the queries. Not sure if that can be “fixed”.

I don’t ever plan on using gatsby myself but maybe this is useful for someone.

---

<div class="post-metadata">

### Author: ![mjmeintjes](https://clojureverse.org/user_avatar/clojureverse.org/mjmeintjes/32/860_2.png) [@mjmeintjes](https://clojureverse.org/u/mjmeintjes)
#### Post date: [September 25, 2018, 4:13am UTC](https://clojureverse.org/t/creating-websites-with-shadow-cljs-gatsby-or-next-js/2912/2 "2018-09-25T04:13:00Z")

</div>

Thanks for this.

I use Gatsby a lot and I’ve been itching to get it working with cljs. But, like you mentioned, they do some weird “magic” things with the raw js code that makes it a difficult to get working.

---

<div class="post-metadata">

### Author: ![thheller](https://clojureverse.org/user_avatar/clojureverse.org/thheller/32/534_2.png) [@thheller](https://clojureverse.org/u/thheller)
#### Post date: [September 27, 2018, 8:56am UTC](https://clojureverse.org/t/creating-websites-with-shadow-cljs-gatsby-or-next-js/2912/4 "2018-09-27T08:56:27Z")

</div>

I did the same experiment with `next.js` and it also works ok-ish.

> **[thheller/next-cljs](https://github.com/thheller/next-cljs)**
>
> Contribute to thheller/next-cljs development by creating an account on GitHub.

The “major” problem however is that their SSR support serializes all data to JSON which means it’ll lose important CLJS type such as sets, keywords, symbols when converting back to EDN. This however could probably be worked around.

As with `gatsby` I don’t think this is a good fit for CLJS but it does work ok-ish.

---

<div class="post-metadata">

### Author: ![groundedSAGE](https://clojureverse.org/letter_avatar_proxy/v4/letter/g/57b2e6/32.png) [@groundedSAGE](https://clojureverse.org/u/groundedSAGE)
#### Post date: [September 28, 2018, 5:22am UTC](https://clojureverse.org/t/creating-websites-with-shadow-cljs-gatsby-or-next-js/2912/5 "2018-09-28T05:22:13Z")

</div>

I’ve looked at a lot of the options out there and was not happy with the overall experience working with these tools. I am quite happy with the experience I have had with Shadow Cljs and think we can put something nice together which is much more closer and integrated with Clojure and Clojurescript (possibly even more stable and simpler). Depending on these other tools to create websites doesn’t offer much other than the large number of plugins produced by the community. Despite this people are still very productive and are making awesome stuff in Clojure and Clojurescript.

---

<div class="post-metadata">

### Author: ![GKlijs](https://clojureverse.org/user_avatar/clojureverse.org/gklijs/32/559_2.png) [@GKlijs](https://clojureverse.org/u/GKlijs)
#### Post date: [September 28, 2018, 6:07am UTC](https://clojureverse.org/t/creating-websites-with-shadow-cljs-gatsby-or-next-js/2912/6 "2018-09-28T06:07:15Z")

</div>

In the future next.js might cut the dependency on webpack, not sure if that would make things easier. Would it be possible to use transit to keep everything in the json?

---

<div class="post-metadata">

### Author: ![thheller](https://clojureverse.org/user_avatar/clojureverse.org/thheller/32/534_2.png) [@thheller](https://clojureverse.org/u/thheller)
#### Post date: [September 28, 2018, 7:20am UTC](https://clojureverse.org/t/creating-websites-with-shadow-cljs-gatsby-or-next-js/2912/7 "2018-09-28T07:20:30Z")

</div>

`transit` is probably possible but still won’t be very efficient since I don’t think you can hook into this globally. So you end up with maybe calling `transit` once per Object. I did not spend too much time with `next.js` though, so it may be possible to customize all of this.

After looking at both options however I do agree that we can probably build something more usable in CLJS itself. I may experiment myself a bit given how much of the heavy-lifting shadow-cljs in regards to CLJS/JS already does. Generating a bit of boilerplate code + HTML should not be that difficult.

---

<div class="post-metadata">

### Author: ![groundedSAGE](https://clojureverse.org/letter_avatar_proxy/v4/letter/g/57b2e6/32.png) [@groundedSAGE](https://clojureverse.org/u/groundedSAGE)
#### Post date: [October 5, 2018, 2:21am UTC](https://clojureverse.org/t/creating-websites-with-shadow-cljs-gatsby-or-next-js/2912/8 "2018-10-05T02:21:30Z")

</div>

All the work I am doing towards creating a Clojure tool similar to Gatsby etc can be tracked here.

> **[groundedSAGE/shadow-jam](https://github.com/groundedSAGE/shadow-jam)**
>
> A JAMstack build tool starter for those who love Clojure - groundedSAGE/shadow-jam

---

<div class="post-metadata">

### Author: ![thheller](https://clojureverse.org/user_avatar/clojureverse.org/thheller/32/534_2.png) [@thheller](https://clojureverse.org/u/thheller)
#### Post date: [April 5, 2019, 2:21pm UTC](https://clojureverse.org/t/creating-websites-with-shadow-cljs-gatsby-or-next-js/2912/9 "2019-04-05T14:21:30Z")

</div>

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.
