Skip to content

Commit 104bcbe

Browse files
authored
add an option to disable ssr for export and deploy (#5821)
1 parent 0097e60 commit 104bcbe

File tree

6 files changed

+65
-8
lines changed

6 files changed

+65
-8
lines changed

reflex/app.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,12 @@
113113
prerequisites,
114114
types,
115115
)
116-
from reflex.utils.exec import get_compile_context, is_prod_mode, is_testing_env
116+
from reflex.utils.exec import (
117+
get_compile_context,
118+
is_prod_mode,
119+
is_testing_env,
120+
should_prerender_routes,
121+
)
117122
from reflex.utils.imports import ImportVar
118123
from reflex.utils.token_manager import TokenManager
119124
from reflex.utils.types import ASGIApp, Message, Receive, Scope, Send
@@ -607,7 +612,7 @@ def __call__(self) -> ASGIApp:
607612
"""
608613
from reflex.vars.base import GLOBAL_CACHE
609614

610-
self._compile(prerender_routes=is_prod_mode())
615+
self._compile(prerender_routes=should_prerender_routes())
611616

612617
config = get_config()
613618

reflex/environment.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,9 @@ class EnvironmentVariables:
657657
# Whether to force a full reload on changes.
658658
VITE_FORCE_FULL_RELOAD: EnvVar[bool] = env_var(False)
659659

660+
# Whether to enable SSR for the frontend.
661+
REFLEX_SSR: EnvVar[bool] = env_var(True)
662+
660663

661664
environment = EnvironmentVariables()
662665

reflex/reflex.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def _run(
204204
args = (frontend,)
205205
kwargs = {
206206
"check_if_schema_up_to_date": True,
207-
"prerender_routes": env == constants.Env.PROD,
207+
"prerender_routes": exec.should_prerender_routes(),
208208
}
209209

210210
# Granian fails if the app is already imported.
@@ -432,6 +432,14 @@ def compile(dry: bool, rich: bool):
432432
type=click.Path(exists=True, path_type=Path, resolve_path=True),
433433
help="Files or directories to exclude from the backend zip. Can be used multiple times.",
434434
)
435+
@click.option(
436+
"--server-side-rendering/--no-server-side-rendering",
437+
"--ssr/--no-ssr",
438+
"ssr",
439+
default=True,
440+
is_flag=True,
441+
help="Whether to enable server side rendering for the frontend.",
442+
)
435443
def export(
436444
zip: bool,
437445
frontend_only: bool,
@@ -440,11 +448,17 @@ def export(
440448
upload_db_file: bool,
441449
env: LITERAL_ENV,
442450
backend_excluded_dirs: tuple[Path, ...] = (),
451+
ssr: bool = True,
443452
):
444453
"""Export the app to a zip file."""
445454
from reflex.utils import export as export_utils
446455
from reflex.utils import prerequisites
447456

457+
if not environment.REFLEX_SSR.is_set():
458+
environment.REFLEX_SSR.set(ssr)
459+
elif environment.REFLEX_SSR.get() != ssr:
460+
ssr = environment.REFLEX_SSR.get()
461+
448462
environment.REFLEX_COMPILE_CONTEXT.set(constants.CompileContext.EXPORT)
449463

450464
should_frontend_run, should_backend_run = prerequisites.check_running_mode(
@@ -467,6 +481,7 @@ def export(
467481
env=constants.Env.DEV if env == constants.Env.DEV else constants.Env.PROD,
468482
loglevel=config.loglevel.subprocess_level(),
469483
backend_excluded_dirs=backend_excluded_dirs,
484+
prerender_routes=ssr,
470485
)
471486

472487

@@ -679,6 +694,14 @@ def makemigrations(message: str | None):
679694
type=click.Path(exists=True, path_type=Path, resolve_path=True),
680695
help="Files or directories to exclude from the backend zip. Can be used multiple times.",
681696
)
697+
@click.option(
698+
"--server-side-rendering/--no-server-side-rendering",
699+
"--ssr/--no-ssr",
700+
"ssr",
701+
default=True,
702+
is_flag=True,
703+
help="Whether to enable server side rendering for the frontend.",
704+
)
682705
def deploy(
683706
app_name: str | None,
684707
app_id: str | None,
@@ -693,6 +716,7 @@ def deploy(
693716
token: str | None,
694717
config_path: str | None,
695718
backend_excluded_dirs: tuple[Path, ...] = (),
719+
ssr: bool = True,
696720
):
697721
"""Deploy the app to the Reflex hosting service."""
698722
from reflex_cli.utils import dependency
@@ -710,6 +734,11 @@ def deploy(
710734

711735
environment.REFLEX_COMPILE_CONTEXT.set(constants.CompileContext.DEPLOY)
712736

737+
if not environment.REFLEX_SSR.is_set():
738+
environment.REFLEX_SSR.set(ssr)
739+
elif environment.REFLEX_SSR.get() != ssr:
740+
ssr = environment.REFLEX_SSR.get()
741+
713742
# Only check requirements if interactive.
714743
# There is user interaction for requirements update.
715744
if interactive:
@@ -742,6 +771,7 @@ def deploy(
742771
loglevel=config.loglevel.subprocess_level(),
743772
upload_db_file=upload_db,
744773
backend_excluded_dirs=backend_excluded_dirs,
774+
prerender_routes=ssr,
745775
)
746776
),
747777
regions=list(region),

reflex/utils/build.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,16 @@ def build():
215215
)
216216
processes.show_progress("Creating Production Build", process, checkpoints)
217217
_duplicate_index_html_to_parent_directory(wdir / constants.Dirs.STATIC)
218-
path_ops.cp(
219-
wdir / constants.Dirs.STATIC / constants.ReactRouter.SPA_FALLBACK,
220-
wdir / constants.Dirs.STATIC / "404.html",
221-
)
218+
219+
spa_fallback = wdir / constants.Dirs.STATIC / constants.ReactRouter.SPA_FALLBACK
220+
if not spa_fallback.exists():
221+
spa_fallback = wdir / constants.Dirs.STATIC / "index.html"
222+
223+
if spa_fallback.exists():
224+
path_ops.cp(
225+
spa_fallback,
226+
wdir / constants.Dirs.STATIC / "404.html",
227+
)
222228

223229
config = get_config()
224230

reflex/utils/exec.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,17 @@ def is_prod_mode() -> bool:
743743
return current_mode == constants.Env.PROD
744744

745745

746+
def should_prerender_routes() -> bool:
747+
"""Check if the app should prerender routes.
748+
749+
Returns:
750+
True if the app should prerender routes.
751+
"""
752+
if not environment.REFLEX_SSR.is_set():
753+
return is_prod_mode()
754+
return environment.REFLEX_SSR.get()
755+
756+
746757
def get_compile_context() -> constants.CompileContext:
747758
"""Check if the app is compiled for deploy.
748759

reflex/utils/export.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def export(
1919
env: constants.Env = constants.Env.PROD,
2020
loglevel: constants.LogLevel = console._LOG_LEVEL,
2121
backend_excluded_dirs: tuple[Path, ...] = (),
22+
prerender_routes: bool = True,
2223
):
2324
"""Export the app to a zip file.
2425
@@ -33,6 +34,7 @@ def export(
3334
env: The environment to use. Defaults to constants.Env.PROD.
3435
loglevel: The log level to use. Defaults to console._LOG_LEVEL.
3536
backend_excluded_dirs: A tuple of files or directories to exclude from the backend zip. Defaults to ().
37+
prerender_routes: Whether to prerender the routes. Defaults to True.
3638
"""
3739
config = get_config()
3840

@@ -58,7 +60,7 @@ def export(
5860

5961
if frontend:
6062
# Ensure module can be imported and app.compile() is called.
61-
prerequisites.get_compiled_app(prerender_routes=True)
63+
prerequisites.get_compiled_app(prerender_routes=prerender_routes)
6264
# Set up .web directory and install frontend dependencies.
6365
build.setup_frontend(Path.cwd())
6466

0 commit comments

Comments
 (0)