[Solved] Only serve ./dist folder


Currently, bitcentivez (git) has the same problem as the original bitcentive, illustrated by this:


The web server is serving directories and files that should not be needed for the static site, which is built into ./dist. I would prefer if the server only served files in ./dist, but I am not sure if this is possible with the done-ssr and steal combination (ssr, in particular).

What configuration changes would be needed to make this work?

For instance, in my “bitcentivez” repo, done-ssr-middleware pulls the configuration for the static site from client/package.json, and therefore serves all of the client directory.

Similarly, steal relies on package.json for configuration.

Attempting to cp client/package.json client/dist/package.json and pointing done-ssr-middleware to client/dist/package.json doesn’t seem to work because there is an error about finding the built ./dist/<etc>/index.js.

It seems it is trying to resolve ./dist relative to an outer directory, assuming the site is built into ./dist/dist, and doesn’t understand or accept package.json being copied to ./dist.

I haven’t been able to find the relevant ssr code that would be causing this, however.

I’m assuming @matthewp might have some ideas in regards to this! :wave:

It might be something super simple. Thanks for any help. :pray:


Why is that a problem?

Well, it’s not necessarily a “problem”, but I am very curious if it is possible, and I feel it should be allowed.

My curiousness stems from wanting to expand my understanding of the frameworks; the examples must be set up the way they are for a reason, and I need help to wrap my head around they are optimal.

If it’s possible, and I think theoretically it should be, I want to prove to myself that ssr sites can be hosted and served in production separate from the presence of directories or files in /client that are used for development (such as the node_modules directory).

I feel that it should be allowed if it is not already because, in my opinion, not serving unnecessary files is more correct, and this provides more encapsulation between development and production.

Is it allowed to serve just ./dist using the provided ssr libraries? Let me know if I’ve misunderstood.

If I’m wrong, please try and acknowledge the merits of my thoughts before questioning my thinking!

Just hoping for some external input to help influence and guide me in developing a solid starter repo.


You can get an idea of what I’m on about in the OP from this commit that:

  1. Changes /dist/steal.production.js —> /steal.production.js.
  2. Adds && cp ./production.html ./package.json ./dist to the build npm run-script.
  3. Adds "client": "../../client/dist/" to the server/config/production.json.

(Actually, don’t need to copy ./production.html in No. 2 because of SSR…)



With express, you should be able to configure it to statically serve whatever you want.


Thanks. Yes, I was able to configure express without issue. The issue is with steal being misconfigured and breaking because it doesn’t seem to work without access to the files or folders above ./dist.

I’m working off the bitcentive and bitballs examples the best I can, but they’re not designed to provide encapsulation of the development files from the production app files. This can be seen, for example, here:

So, I don’t think this has even been attempted officially by any of the existing apps you’ve worked on.

I was hoping @matthewp would chime in since he’s the steal expert, and this seems like something steal should be able to be configured to do with just a couple of settings out of the box.


@matthewp Hope you’re doing well.

In which repo would I open this as an issue, steal or steal-tools?

Sorry for being such a huge noob and not knowing that. Thanks.


You probably need to use bundlesPath and renderingBaseURL to make this work. I’m guessing bundlesPath because bundles/ and renderingBaseURL is /.

Alternatively you could create a folder, let’s call it prod/ and stick your package.json and dist/ files in there. Then you wouldn’t need any added configuration.


I think I’m going to try sticking dist/ and package.json in prod/ and see how that goes. Thanks!


I’m very happy that I got it working thanks to @matthewp’s help! Here’s what I had to do:

First of all, I had to update my build npm run-script like so:

"build": "rm -rf ./prod && mkdir ./prod && node build && cp -r ./node_modules/events ./dist/node_modules && mv ./dist ./prod && cp ./package.json ./favicon.ico ./prod"

Next, I had to update my server config in production.json to point to the new prod directory:

diff --git a/.gitignore b/.gitignore
index 811797d..bab3a59 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
diff --git a/server/config/production.json b/server/config/production.json
index f9745c5..dd7e9a5 100644
--- a/server/config/production.json
+++ b/server/config/production.json
@@ -1,4 +1,5 @@
+  "client": "../../client/prod/",
   "port": "PORT",
   "host": "bitcentivez.herokuapp.com",
   "mongodb": "MONGODB_URI"

Images in .stache had the wrong URLs (like img/blah.png instead of dist/img/blah.png) so I had to update all my <img/> tags to use joinBase like so:

<img src="{{joinBase('img/github.svg')}}" alt="GitHub logo">

Finally, because only .less images were in prod/dist/img, I had to add a glob to bundleAssets:

diff --git a/client/build.js b/client/build.js
index dd5e573..b68b69d 100644
--- a/client/build.js
+++ b/client/build.js
@@ -4,6 +4,9 @@ const buildPromise = stealTools.build(
     minify: false,
-    bundleAssets: true,
-  }
+    bundleAssets: {
+      infer: true,
+      glob: ['img/**/*'],
+    },
+  },

Even though the build npm run-script has become kind of long, I feel this has really improved the quality of the project and it just makes way more sense to have this encapsulation, because it forces you to do things correctly like use joinBase instead of hard-coding your URLs. The cp -r ./node_modules/events ./dist/node_modules part of the build npm run-script is another separate issue raised here:


Another [now solved] issue: SSR doesn’t seem to prepend dist/ using joinBase so <img/> URLs come down 404ing until eventual client app reattachment which does prepend dist/.