├── .funcignore
├── .github
└── workflows
│ ├── azure-static-web-apps-ashy-grass-090f92903.yml
│ └── azure-static-web-apps-yellow-sky-07aa3e70f.yml
├── .gitignore
├── .node-version
├── .npmrc
├── .vscode
├── extensions.json
├── launch.json
├── settings.json
└── tasks.json
├── README.md
├── app
├── entry.client.tsx
├── entry.server.tsx
├── root.tsx
├── routes
│ ├── 404.tsx
│ ├── index.tsx
│ └── page-2.tsx
└── styles
│ ├── global.css
│ └── index.css
├── azure
├── function.json
└── function
│ ├── handler.js
│ └── index.js
├── host.json
├── package-lock.json
├── package.json
├── proxies.json
├── public
├── favicon.png
├── index.html
└── staticwebapp.config.json
├── remix.config.js
├── remix.env.d.ts
└── tsconfig.json
/.funcignore:
--------------------------------------------------------------------------------
1 | *.js.map
2 | *.ts
3 | .git*
4 | .vscode
5 | local.settings.json
6 | test
7 | tsconfig.json
--------------------------------------------------------------------------------
/.github/workflows/azure-static-web-apps-ashy-grass-090f92903.yml:
--------------------------------------------------------------------------------
1 | name: Azure Static Web Apps CI/CD
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 | types: [opened, synchronize, reopened, closed]
9 | branches:
10 | - main
11 |
12 | jobs:
13 | build_and_deploy_job:
14 | if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
15 | runs-on: ubuntu-latest
16 | name: Build and Deploy Job
17 | steps:
18 | - uses: actions/checkout@v2
19 | with:
20 | submodules: true
21 | - name: Build And Deploy
22 | id: builddeploy
23 | uses: Azure/static-web-apps-deploy@v1
24 | with:
25 | azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_GRASS_090F92903 }}
26 | repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
27 | action: "upload"
28 | ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
29 | # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
30 | app_location: "/" # App source code path
31 | api_location: "/" # Api source code path - optional
32 | output_location: "/public" # Built app content directory - optional
33 | ###### End of Repository/Build Configurations ######
34 |
35 | close_pull_request_job:
36 | if: github.event_name == 'pull_request' && github.event.action == 'closed'
37 | runs-on: ubuntu-latest
38 | name: Close Pull Request Job
39 | steps:
40 | - name: Close Pull Request
41 | id: closepullrequest
42 | uses: Azure/static-web-apps-deploy@v1
43 | with:
44 | azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_GRASS_090F92903 }}
45 | action: "close"
46 |
--------------------------------------------------------------------------------
/.github/workflows/azure-static-web-apps-yellow-sky-07aa3e70f.yml:
--------------------------------------------------------------------------------
1 | name: Azure Static Web Apps CI/CD
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 | types: [opened, synchronize, reopened, closed]
9 | branches:
10 | - main
11 |
12 | jobs:
13 | build_and_deploy_job:
14 | if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
15 | runs-on: ubuntu-latest
16 | name: Build and Deploy Job
17 | steps:
18 | - uses: actions/checkout@v2
19 | with:
20 | submodules: true
21 | - name: Build And Deploy
22 | id: builddeploy
23 | uses: Azure/static-web-apps-deploy@v1
24 | with:
25 | azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_YELLOW_SKY_07AA3E70F }}
26 | repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
27 | action: "upload"
28 | ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
29 | # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
30 | app_location: "/" # App source code path
31 | api_location: "/" # Api source code path - optional
32 | output_location: "/public" # Built app content directory - optional
33 | ###### End of Repository/Build Configurations ######
34 |
35 | close_pull_request_job:
36 | if: github.event_name == 'pull_request' && github.event.action == 'closed'
37 | runs-on: ubuntu-latest
38 | name: Close Pull Request Job
39 | steps:
40 | - name: Close Pull Request
41 | id: closepullrequest
42 | uses: Azure/static-web-apps-deploy@v1
43 | with:
44 | azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_YELLOW_SKY_07AA3E70F }}
45 | action: "close"
46 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 |
24 | # nyc test coverage
25 | .nyc_output
26 |
27 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
28 | .grunt
29 |
30 | # Bower dependency directory (https://bower.io/)
31 | bower_components
32 |
33 | # node-waf configuration
34 | .lock-wscript
35 |
36 | # Compiled binary addons (https://nodejs.org/api/addons.html)
37 | build/Release
38 |
39 | # Dependency directories
40 | node_modules/
41 | jspm_packages/
42 |
43 | # TypeScript v1 declaration files
44 | typings/
45 |
46 | # Optional npm cache directory
47 | .npm
48 |
49 | # Optional eslint cache
50 | .eslintcache
51 |
52 | # Optional REPL history
53 | .node_repl_history
54 |
55 | # Output of 'npm pack'
56 | *.tgz
57 |
58 | # Yarn Integrity file
59 | .yarn-integrity
60 |
61 | # dotenv environment variables file
62 | .env
63 | .env.test
64 |
65 | # parcel-bundler cache (https://parceljs.org/)
66 | .cache
67 |
68 | # next.js build output
69 | .next
70 |
71 | # nuxt.js build output
72 | .nuxt
73 |
74 | # vuepress build output
75 | .vuepress/dist
76 |
77 | # Serverless directories
78 | .serverless/
79 |
80 | # FuseBox cache
81 | .fusebox/
82 |
83 | # DynamoDB Local files
84 | .dynamodb/
85 |
86 | # TypeScript output
87 | dist
88 | out
89 |
90 | # Azure Functions artifacts
91 | bin
92 | obj
93 | appsettings.json
94 | local.settings.json
95 |
96 | node_modules
97 |
98 | /.cache
99 | /azure/function/build
100 | /public/build
101 |
--------------------------------------------------------------------------------
/.node-version:
--------------------------------------------------------------------------------
1 | 14
2 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | @remix-run:registry=https://npm.remix.run
2 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "ms-azuretools.vscode-azurefunctions"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Attach to Node Functions",
6 | "type": "node",
7 | "request": "attach",
8 | "port": 9229,
9 | "preLaunchTask": "func: host start"
10 | }
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "azureFunctions.deploySubpath": ".",
3 | "azureFunctions.postDeployTask": "npm install (functions)",
4 | "azureFunctions.projectLanguage": "TypeScript",
5 | "azureFunctions.projectRuntime": "~3",
6 | "debug.internalConsoleOptions": "neverOpen",
7 | "azureFunctions.preDeployTask": "npm prune (functions)"
8 | }
9 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "type": "func",
6 | "command": "host start",
7 | "problemMatcher": "$func-node-watch",
8 | "isBackground": true,
9 | "dependsOn": "npm build (functions)"
10 | },
11 | {
12 | "type": "shell",
13 | "label": "npm build (functions)",
14 | "command": "npm run build",
15 | "dependsOn": "npm install (functions)",
16 | "problemMatcher": "$tsc"
17 | },
18 | {
19 | "type": "shell",
20 | "label": "npm install (functions)",
21 | "command": "npm install"
22 | },
23 | {
24 | "type": "shell",
25 | "label": "npm prune (functions)",
26 | "command": "npm prune --production",
27 | "dependsOn": "npm build (functions)",
28 | "problemMatcher": []
29 | }
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Welcome to Remix!
2 |
3 | - [Remix Docs](https://docs.remix.run)
4 | - [Customer Dashboard](https://remix.run/dashboard)
5 |
6 | ## Development
7 |
8 | From your terminal:
9 |
10 | ```sh
11 | npm run dev
12 | ```
13 |
--------------------------------------------------------------------------------
/app/entry.client.tsx:
--------------------------------------------------------------------------------
1 | import ReactDOM from "react-dom";
2 | import { RemixBrowser } from "remix";
3 |
4 | ReactDOM.hydrate(
{error.message}59 |
60 | Replace this UI with what you want users to see when your app throws 61 | uncaught errors. 62 |
63 |34 | Check out the docs to get started. 35 |
36 |Message from the loader: {data.message}
37 |Welcome to Page 2👋
11 | Go back home. 12 | > 13 | ); 14 | }; 15 | 16 | export default Page; 17 | export { meta }; 18 | -------------------------------------------------------------------------------- /app/styles/global.css: -------------------------------------------------------------------------------- 1 | :focus:not(:focus-visible) { 2 | outline: none; 3 | } 4 | 5 | body { 6 | font-family: sans-serif; 7 | } 8 | 9 | footer { 10 | text-align: center; 11 | color: #ccc; 12 | padding-top: 80px; 13 | } 14 | -------------------------------------------------------------------------------- /app/styles/index.css: -------------------------------------------------------------------------------- 1 | /* 2 | * when the user visits this page, this style will apply, when they leave, it 3 | * will get unloaded, so don't worry so much about conflicting styles between 4 | * pages! 5 | */ 6 | -------------------------------------------------------------------------------- /azure/function.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": [ 3 | { 4 | "authLevel": "anonymous", 5 | "type": "httpTrigger", 6 | "direction": "in", 7 | "name": "req" 8 | }, 9 | { 10 | "type": "http", 11 | "direction": "out", 12 | "name": "$return" 13 | } 14 | ], 15 | "scriptFile": "./function/index.js" 16 | } 17 | -------------------------------------------------------------------------------- /azure/function/handler.js: -------------------------------------------------------------------------------- 1 | const { 2 | createRequestHandler: createRemixRequestHandler, 3 | } = require("@remix-run/server-runtime"); 4 | 5 | const { 6 | formatServerError, 7 | Headers: NodeHeaders, 8 | Request: NodeRequest, 9 | Response: NodeResponse, 10 | RequestInit: NodeRequestInit, 11 | } = require("@remix-run/node"); 12 | 13 | function createRequestHandler({ 14 | build, 15 | getLoadContext, 16 | mode = process.env.NODE_ENV, 17 | }) { 18 | let platform = { formatServerError }; 19 | let handleRequest = createRemixRequestHandler(build, platform, mode); 20 | 21 | return async (_context, req) => { 22 | let request = createRemixRequest(req); 23 | let loadContext = 24 | typeof getLoadContext === "function" ? getLoadContext(req) : undefined; 25 | 26 | let response = await handleRequest(request, loadContext); 27 | 28 | return { 29 | status: response.status, 30 | headers: response.headers.raw(), 31 | body: await response.text(), 32 | }; 33 | }; 34 | } 35 | 36 | function createRemixHeaders(requestHeaders) { 37 | let headers = new NodeHeaders(); 38 | 39 | for (let [key, value] of Object.entries(requestHeaders)) { 40 | if (!value) continue; 41 | headers.set(key, value); 42 | } 43 | 44 | return headers; 45 | } 46 | 47 | function createRemixRequest(req) { 48 | let url = req.headers["x-ms-original-url"]; 49 | 50 | let init = { 51 | method: req.method || "GET", 52 | headers: createRemixHeaders(req.headers), 53 | }; 54 | 55 | if (req.body && req.method !== "GET" && req.method !== "HEAD") { 56 | init.body = req.body; 57 | } 58 | 59 | return new NodeRequest(url, init); 60 | } 61 | 62 | module.exports = { createRequestHandler }; 63 | -------------------------------------------------------------------------------- /azure/function/index.js: -------------------------------------------------------------------------------- 1 | const { installGlobals } = require("@remix-run/node"); 2 | const { createRequestHandler } = require("./handler"); 3 | 4 | installGlobals(); 5 | 6 | module.exports = createRequestHandler({ build: require("./build") }); 7 | -------------------------------------------------------------------------------- /host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "logging": { 4 | "applicationInsights": { 5 | "samplingSettings": { 6 | "isEnabled": true, 7 | "excludedTypes": "Request" 8 | } 9 | } 10 | }, 11 | "extensions": { 12 | "http": { 13 | "routePrefix": "api" 14 | } 15 | }, 16 | "extensionBundle": { 17 | "id": "Microsoft.Azure.Functions.ExtensionBundle", 18 | "version": "[2.*, 3.0.0)" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "remix-on-azure", 4 | "description": "", 5 | "license": "", 6 | "scripts": { 7 | "build": "remix build", 8 | "dev": "cross-env NODE_ENV=development swa start ./public --run \"remix dev\" --api-location .", 9 | "start": "remix-serve build", 10 | "prepare": "remix setup node" 11 | }, 12 | "dependencies": { 13 | "@remix-run/dev": "1.1.3", 14 | "@remix-run/node": "1.1.3", 15 | "@remix-run/react": "1.1.3", 16 | "@remix-run/serve": "1.1.3", 17 | "react": "17.0.2", 18 | "react-dom": "17.0.2", 19 | "remix": "1.1.3" 20 | }, 21 | "devDependencies": { 22 | "@azure/functions": "3.0.0", 23 | "@azure/static-web-apps-cli": "0.8.2", 24 | "@types/react": "17.0.38", 25 | "@types/react-dom": "17.0.11", 26 | "cross-env": "7.0.3", 27 | "typescript": "4.5.4" 28 | }, 29 | "engines": { 30 | "node": ">=14" 31 | }, 32 | "sideEffects": false 33 | } 34 | -------------------------------------------------------------------------------- /proxies.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/proxies", 3 | "proxies": {} 4 | } 5 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcansh/remix-on-azure/fb8e391c7627397340de0da3de126ecf1d90e109/public/favicon.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |