-
Notifications
You must be signed in to change notification settings - Fork 1.7k
fix: Handle periods in dynamic route segments for production mode #6129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -132,6 +132,56 @@ def replace_brackets_with_keywords(input_string: str) -> str: | |
| ) | ||
|
|
||
|
|
||
| def get_dynamic_route_prefixes(routes: list[str]) -> list[str]: | ||
| """Get route prefixes for dynamic routes to use with sirv --ignores. | ||
|
|
||
| sirv treats URLs with extensions (periods) as asset requests, not SPA routes. | ||
| This function extracts route patterns that have dynamic segments, so they can | ||
| be excluded from asset detection using sirv's --ignores flag. | ||
|
|
||
| Example: | ||
| >>> get_dynamic_route_prefixes(["/posts/[slug]", "/data/[version]/info"]) | ||
| ['^/posts/', '^/data/'] | ||
|
|
||
| Args: | ||
| routes: List of route strings. | ||
|
|
||
| Returns: | ||
| List of regex patterns for sirv --ignores flag. | ||
| """ | ||
| prefixes = [] | ||
| for route in routes: | ||
| # Check if route has dynamic segments | ||
| if get_route_args(route): | ||
| # Extract the prefix up to the first dynamic segment | ||
| parts = route.split("/") | ||
| prefix_parts = [] | ||
| for part in parts: | ||
| # Stop at first dynamic segment | ||
| if ( | ||
| constants.RouteRegex.ARG.match(part) | ||
| or constants.RouteRegex.OPTIONAL_ARG.match(part) | ||
| or constants.RouteRegex.STRICT_CATCHALL.match(part) | ||
| or constants.RouteRegex.OPTIONAL_CATCHALL.match(part) | ||
| or part == constants.RouteRegex.SPLAT_CATCHALL | ||
| ): | ||
| break | ||
| prefix_parts.append(part) | ||
|
|
||
| # Build prefix pattern (e.g., "/posts" -> "^/posts/") | ||
| prefix = "/".join(prefix_parts) | ||
| # Ensure prefix starts with / for absolute path matching | ||
| if not prefix.startswith("/"): | ||
| prefix = "/" + prefix | ||
| if prefix and prefix != "/": | ||
| # Add trailing slash and anchor to start for sirv pattern | ||
| pattern = f"^{prefix}/" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should use |
||
| if pattern not in prefixes: | ||
| prefixes.append(pattern) | ||
|
|
||
| return prefixes | ||
|
|
||
|
|
||
| def route_specificity(keyworded_route: str) -> tuple[int, int, int]: | ||
| """Get the specificity of a route with keywords. | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -167,23 +167,39 @@ def _update_react_router_config(config: Config, prerender_routes: bool = False): | |
| return f"export default {json.dumps(react_router_config)};" | ||
|
|
||
|
|
||
| def _compile_package_json(): | ||
| def _compile_package_json(dynamic_route_prefixes: list[str] | None = None): | ||
| """Compile package.json with optional dynamic route handling. | ||
|
|
||
| Args: | ||
| dynamic_route_prefixes: List of route prefix patterns for sirv --ignores. | ||
| """ | ||
| # Build prod command with --ignores flags for dynamic routes | ||
| prod_command = constants.PackageJson.Commands.PROD | ||
| if dynamic_route_prefixes: | ||
| # Add --ignores flag for each dynamic route prefix | ||
| ignores = " ".join(f"--ignores '{prefix}'" for prefix in dynamic_route_prefixes) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use |
||
| prod_command = f"{prod_command} {ignores}" | ||
|
|
||
| return templates.package_json_template( | ||
| scripts={ | ||
| "dev": constants.PackageJson.Commands.DEV, | ||
| "export": constants.PackageJson.Commands.EXPORT, | ||
| "prod": constants.PackageJson.Commands.PROD, | ||
| "prod": prod_command, | ||
| }, | ||
| dependencies=constants.PackageJson.DEPENDENCIES, | ||
| dev_dependencies=constants.PackageJson.DEV_DEPENDENCIES, | ||
| overrides=constants.PackageJson.OVERRIDES, | ||
| ) | ||
|
|
||
|
|
||
| def initialize_package_json(): | ||
| """Render and write in .web the package.json file.""" | ||
| def initialize_package_json(dynamic_route_prefixes: list[str] | None = None): | ||
| """Render and write in .web the package.json file. | ||
|
|
||
| Args: | ||
| dynamic_route_prefixes: List of route prefix patterns for sirv --ignores. | ||
| """ | ||
| output_path = get_web_dir() / constants.PackageJson.PATH | ||
| output_path.write_text(_compile_package_json()) | ||
| output_path.write_text(_compile_package_json(dynamic_route_prefixes)) | ||
|
|
||
|
|
||
| def _compile_vite_config(config: Config): | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.