feat(node): support conditional SPA index fallback (#582)

* fix(caddy): standardize and improve security in Caddyfile templates

- Standardize security headers and compression settings across Node and static file providers.
- Improve health check handling by using log_skip to reduce log noise.
- Implement custom error page support for static file deployments.
- Update documentation to reflect the default Caddyfile capabilities.
- Add Railway proxy range to trusted proxies for improved network compatibility.

Generated-by: aiautocommit

* test(example): add node-astro-static-404 reproduction case

- Create a new example project to reproduce static site behavior with custom 404 pages.
- Configure Staticfile with index_fallback set to false to test 404 handling.
- Include an integration test suite validating that unknown routes correctly return the custom 404 page.

Generated-by: aiautocommit

* feat(node): support conditional SPA index fallback

- Allow the Caddy configuration to disable index.html fallback for node SPA deployments.
- Expose an option to read `index_fallback` from a Staticfile, defaulting to true for Node SPA projects.

Generated-by: aiautocommit

* docs: document Staticfile index_fallback configuration for Node SPAs

Generated-by: aiautocommit

* test: update snapshot

* Revert "fix(caddy): standardize and improve security in Caddyfile templates"

This reverts commit 6c8f57f5149ca1cc84d04d8eded8cdf7a928a66d.

* refactor: rename static-404 example to spa-staticfile

- Renamed the node-astro-static-404 example to node-spa-staticfile to better reflect its purpose as a SPA configuration example.
- Added a readme explaining the use case for customizing SPA behavior via a Staticfile.

Generated-by: aiautocommit

* refactor(node): update SPA detection and deployment configuration

*   Include Expo in SPA detection logic to ensure consistent behavior.
*   Standardize framework naming capitalization.
*   Update index fallback lookup to use a generalized helper function.

Generated-by: aiautocommit

* refactor(staticfile): align index fallback logic with provider requirements

- Centralize index fallback resolution in GetIndexFallback to differentiate between user-defined values and defaults.
- Update the Staticfile provider to explicitly set the default to false while maintaining compatibility for node SPA implementations.
- Improve Caddyfile template documentation regarding SPA routing behavior.

Generated-by: aiautocommit

* chore: update build plan dependencies and environment variables

- Bump railpack-builder and runtime versions to 2026.6.11
- Update Caddy version to 2.11.4
- Add NPM_CONFIG_FETCH_RETRIES to node environment variables
- Improve Caddyfile SPA routing logic
- Rename snapshot file to reflect the correct test case target

Generated-by: aiautocommit

* test: update Caddyfile try_files comments in snapshots

Generated-by: aiautocommit

* feat(node): treat expo start as a default command

- Add DefaultExpoStartCommand constant to identify the default Expo start script.
- Update hasCustomStartCommand to exclude Expo's default command from the custom command check.
- Update tests to reflect that Expo default behavior is no longer considered custom.

Generated-by: aiautocommit

* test: update snapshot
This commit is contained in:
Michael Bianco
2026-06-18 10:19:31 +02:00
committed by GitHub
parent ec1b056ade
commit 73c31ee4ef
26 changed files with 5836 additions and 30 deletions
+24
View File
@@ -0,0 +1,24 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
# jetbrains setting folder
.idea/
+1
View File
@@ -0,0 +1 @@
index_fallback: false
@@ -0,0 +1,5 @@
// @ts-check
import { defineConfig } from "astro/config";
// https://astro.build/config
export default defineConfig({});
File diff suppressed because it is too large Load Diff
+15
View File
@@ -0,0 +1,15 @@
{
"name": "node-astro-static-404",
"private": true,
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"astro": "^5.13.7"
}
}
+1
View File
@@ -0,0 +1 @@
Ensures that a SPA with a Staticfile can customize SPA-related configuration, just like the Staticfile provider.
@@ -0,0 +1,19 @@
---
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title>
</head>
<body>
<slot />
</body>
</html>
@@ -0,0 +1,9 @@
---
import Layout from "../layouts/layout.astro";
---
<Layout title="404">
<main>
I'm a 404 page
</main>
</Layout>
@@ -0,0 +1,9 @@
---
import Layout from "../layouts/layout.astro";
---
<Layout title="Test Static">
<main>
HI I'M THE HOME PAGE
</main>
</Layout>
+19
View File
@@ -0,0 +1,19 @@
[
{
"httpCheck": {
"path": "/",
"expected": 200,
"internalPort": 80,
"expectedOutput": "HI I'M THE HOME PAGE"
}
},
{
// Reproduces https://github.com/railwayapp/railpack/issues/553
// Staticfile index_fallback: false should return 404 for unknown paths (not index.html)
"httpCheck": {
"path": "/21312",
"expected": 404,
"internalPort": 80
}
}
]
@@ -0,0 +1,5 @@
{
"extends": "astro/tsconfigs/strict",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"]
}