Publish a Remix App on Azure Static websites.

By: gmarr

Published On: 2022-04-11

Before my notes, here is some housekeeping:

First

The original articles I used for my approach are these:

Second

Here's my repo with the base project.

Now, to the notes!

Remix is a full-stack web framework, and it truly is full-stack. The lines between front-end and backend are so blurred that you're doing both in a single file. It truly is a thing of beauty.

Most of the superpowers of this framework come from the basic premise that the site should be rendered on the server-side and then, send to the client. So, if this is the case, why should I want to publish my site in a service that clearly states "Static Site"?

Well, in my case, it was practicality. Azure static sites is an amazing service that let you publish a static side, directly from Github and add practical features like CI/CD out of the box. So, in summary, you can code your entire site, push it to GitHub, and from there, publish it on Azure with a few clicks. Once is published, every change that is pushed to Github is re-published automatically.

Here's the basic folder structure (I'm kind of omitting the files that actually come with Remix) :

├── app
│   ├── routes
│   │   ├── index.tsx
├── azure
│   ├── function
│   │   ├── handler.js
│   │   ├── index.js
│   │   ├── build
│   │   │   ├── index.js
│   ├── function.json
├── public
│   ├── index.html
│   ├── staticwebapp.config.json
├── host.json
├── package.json
├── proxies.json
├── remix.config.js
// remix.config.js

/**
 * @type {import('@remix-run/dev').AppConfig}
 */
 module.exports = {
  appDirectory: "app",
  browserBuildDirectory: "public/build",
  publicPath: "/build/",
  serverBuildDirectory: "azure/function/build",
  devServerPort: 8002,
};
//package.json
{
  "name": "remix-template-remix",
  "private": true,
  "description": "",
  "license": "",
  "sideEffects": false,
  "scripts": {
    "build": "remix build",
    "dev": "remix dev",
    "start": "remix-serve build"
  },
  "dependencies": {
    "@remix-run/node": "^1.3.4",
    "@remix-run/react": "^1.3.4",
    "@remix-run/serve": "^1.3.4",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  },
  "devDependencies": {
    "@azure/functions": "^3.0.0",
    "@remix-run/dev": "^1.3.4",
    "@remix-run/eslint-config": "^1.3.4",
    "@types/react": "^17.0.24",
    "@types/react-dom": "^17.0.9",
    "eslint": "^8.11.0",
    "typescript": "^4.5.5"
  },
  "engines": {
    "node": ">=14"
  }
}
//proxies.json
{
    "$schema": "http://json.schemastore.org/proxies",
    "proxies": {}
  }
//host.json
{
    "version": "2.0",
    "logging": {
      "applicationInsights": {
        "samplingSettings": {
          "isEnabled": true,
          "excludedTypes": "Request"
        }
      }
    },
    "extensions": {
      "http": {
        "routePrefix": "api"
      }
    },
    "extensionBundle": {
      "id": "Microsoft.Azure.Functions.ExtensionBundle",
      "version": "[2.*, 3.0.0)"
    }
  }
// staticwebapp.config.json

{
    "platform": {
      "apiRuntime": "node:16"
    },
    "routes": [
      {
        "route": "/",
        "rewrite": "/api/azure"
      },
      {
        "route": "/index.html",
        "rewrite": "/api/azure"
      }
    ],
    "navigationFallback": {
      "rewrite": "/api/azure"
    }
  }