Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 101 additions & 4 deletions docs/advanced_onboarding/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,20 @@ config = rx.Config(
)
```

See the [config reference](https://reflex.dev/docs/api-reference/config/) for all the parameters available.
See the [config reference](/docs/api-reference/config/) for all the parameters available.

## Environment Variables

You can override the configuration file by setting environment variables.
For example, to override the `frontend_port` setting, you can set the `FRONTEND_PORT` environment variable.
Any config parameter can be overridden by setting an environment variable with the `REFLEX_` prefix and the parameter name in uppercase. Environment variables take precedence over values set in `rxconfig.py`.

For example, to override the `frontend_port` setting:

```bash
FRONTEND_PORT=3001 uv run reflex run
REFLEX_FRONTEND_PORT=3001 uv run reflex run
```

The [config reference](/docs/api-reference/config/) lists the environment variable corresponding to each config parameter. Reflex also honors additional environment variables that are not config parameters — see [environment variables](/docs/api-reference/environment-variables/) for those.

## Command Line Arguments

Finally, you can override the configuration file and environment variables by passing command line arguments to `uv run reflex run`.
Expand All @@ -44,6 +47,100 @@ uv run reflex run --frontend-port 3001

See the [CLI reference](/docs/api-reference/cli) for all the arguments available.

## Loading a .env File

Set `env_file` (or the `REFLEX_ENV_FILE` environment variable) to load environment variables from a dotenv-format file before the config is read. This requires the `python-dotenv` package to be installed.

```python
config = rx.Config(
app_name="my_app_name",
env_file=".env",
)
```

Multiple files can be passed separated by `os.pathsep` (`:` on Linux/macOS, `;` on Windows); when several files set the same variable, the first file in the list takes precedence. Values from an env file override variables already present in the environment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Correct dotenv precedence description

The documentation reverses the precedence between dotenv values and variables already present in the process environment. Explicit process-environment values take precedence, so this statement gives users the wrong expectation when both sources define the same variable.

Suggested change
Multiple files can be passed separated by `os.pathsep` (`:` on Linux/macOS, `;` on Windows); when several files set the same variable, the first file in the list takes precedence. Values from an env file override variables already present in the environment.
Multiple files can be passed separated by `os.pathsep` (`:` on Linux/macOS, `;` on Windows); when several files set the same variable, the first file in the list takes precedence. Variables already present in the environment override values from an env file.

Knowledge Base Used: Config and Environment System


Because the env file is loaded before config overrides are applied, it can set any `REFLEX_*` variable, e.g. `REFLEX_FRONTEND_PORT=3001`.

## The App Module

`app_name` tells Reflex where your app lives: by default it imports the module `<app_name>.<app_name>` (the layout created by `reflex init`) and expects it to define a module-level variable named `app`, an instance of `rx.App`.

Set `app_module_import` to load the app from a different module, e.g. a `src` layout or a package entry point:

```python
config = rx.Config(
app_name="my_app_name",
# Equivalent to `from mypkg.main import app`.
app_module_import="mypkg.main",
)
```

The imported module must still define `app` at module level.

## Ports, Hosts and URLs

- `frontend_port` (default `3000`) and `backend_port` (default `8000`) control which ports the frontend and backend listen on. In dev mode, if a port is taken, the next available port is used.
- `backend_host` (default `0.0.0.0`) is the address the backend server binds to.
- `api_url` (default `http://localhost:8000`) is the URL the user's **browser** uses to reach the backend. You typically don't need to set it: when `api_url` points at localhost, the frontend substitutes the domain the app was served from, so a backend reachable at the same address as the frontend (e.g. behind a reverse proxy or load balancer) is found automatically. Set `api_url` only when the backend is listening on a different address than the frontend, e.g. `https://api.example.com`.
- `deploy_url` (default `http://localhost:3000`) is the public URL where the **frontend** is hosted. Reflex uses it wherever an absolute frontend URL is needed — most notably for the links in the generated `sitemap.xml`. It is also the origin browsers will present when connecting to the backend, which matters for CORS (below).

## CORS

The backend only accepts cross-origin requests from origins listed in `cors_allowed_origins`. The default, `["*"]`, allows any origin — convenient in development, but in production restrict it to the origins your frontend is actually served from (typically the origin of `deploy_url`):

```python
config = rx.Config(
app_name="my_app_name",
api_url="https://api.example.com",
deploy_url="https://example.com",
cors_allowed_origins=["https://example.com"],
)
```

The setting applies to both regular HTTP endpoints and the WebSocket connection. As an environment variable, pass a comma-separated list:

```bash
REFLEX_CORS_ALLOWED_ORIGINS="https://example.com,https://www.example.com" uv run reflex run
```

## Path Prefixes

By default the frontend is served from the root of its domain and backend routes are mounted at the root of the backend server. Two settings change that, e.g. when the app shares a domain with other services behind a reverse proxy:

- `frontend_path` serves the frontend under a sub-path: `frontend_path="/app"` serves the frontend at `http://localhost:3000/app`.
- `backend_path` mounts all backend routes under a prefix: `backend_path="/api"` mounts the event WebSocket and the `/ping`, `/_upload`, `/_health`, and `/_all_routes` endpoints under `/api`. The prefix is automatically included in the backend URLs baked into the frontend. Routes are registered at startup, so changing it requires a full `reflex run` restart.

Both values are normalized to start with a `/`.

## Plugins

Plugins extend the Reflex compiler. Add plugin instances via the `plugins` parameter, and disable plugins that are enabled by default (like the sitemap plugin) with `disable_plugins`:

```python
config = rx.Config(
app_name="my_app_name",
plugins=[
rx.plugins.SitemapPlugin(),
rx.plugins.TailwindV4Plugin(),
],
# Or turn off a default-enabled plugin:
# disable_plugins=[rx.plugins.SitemapPlugin],
)
```

Plugins can also be specified in the environment as fully qualified import paths, separated by `:`. Plugins specified this way are instantiated without arguments, so plugins that require constructor arguments must be configured in `rxconfig.py`.

- `REFLEX_PLUGINS` **replaces** the `plugins` list from `rxconfig.py`.
- `REFLEX_EXTRA_PLUGINS` **appends** to the configured plugins, skipping any that are already configured or disabled.
- `REFLEX_DISABLE_PLUGINS` lists plugin classes to disable.

```bash
REFLEX_EXTRA_PLUGINS="reflex.plugins.SitemapPlugin" uv run reflex run
```

See the [plugins reference](/docs/api-reference/plugins/) for the available plugins and how to write your own.

## Customizable App Data Directory

The `REFLEX_DIR` environment variable can be set, which allows users to set the location where Reflex writes helper tools like Bun and NodeJS.
Expand Down
52 changes: 30 additions & 22 deletions docs/app/agent_files/_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ def generate_api_reference_markdown_content(
class_fields: Sequence[tuple[str, str, str]],
fields: Sequence[tuple[str, str, str]],
methods: Sequence[tuple[str, str]],
env_var_prefix: str | None = None,
) -> str:
"""Generate markdown content for a dynamic API reference page.

Expand All @@ -502,6 +503,8 @@ def generate_api_reference_markdown_content(
class_fields: The class field rows as name, type, description.
fields: The field rows as name, type, description.
methods: The method rows as signature, description.
env_var_prefix: If set, add a column listing the environment variable
(prefix + field name in uppercase) that overrides each field.

Returns:
The generated markdown content.
Expand All @@ -520,16 +523,26 @@ def generate_api_reference_markdown_content(
("Class Fields", class_fields),
("Fields", fields),
):
table = _markdown_table(
["Prop", "Description"],
[
if env_var_prefix is not None and heading == "Fields":
headers = ["Prop", "Environment Variable", "Description"]
rows = [
(
f"`{name}: {type_display}`",
f"`{env_var_prefix}{name.upper()}`",
field_description,
)
for name, type_display, field_description in field_rows
],
)
]
else:
headers = ["Prop", "Description"]
rows = [
(
f"`{name}: {type_display}`",
field_description,
)
for name, type_display, field_description in field_rows
]
table = _markdown_table(headers, rows)
if table:
lines.extend([f"## {heading}", "", *table, ""])

Expand All @@ -554,26 +567,23 @@ def generate_class_api_reference_markdown(
url_path: Path,
title: str,
cls: type,
extra_fields: Sequence[object] = (),
env_var_prefix: str | None = None,
) -> tuple[Path, str]:
"""Generate a dynamic class API reference markdown asset.

Args:
url_path: The public markdown asset path.
title: The page title.
cls: The class to document.
extra_fields: Extra docgen fields to include.
env_var_prefix: If set, list the environment variable that overrides
each field (prefix + field name in uppercase).

Returns:
The public path and generated markdown content.
"""
from reflex_docgen import FieldDocumentation, generate_class_documentation
from reflex_docgen import generate_class_documentation

doc = generate_class_documentation(cls)
fields = (
*doc.fields,
*(field for field in extra_fields if isinstance(field, FieldDocumentation)),
)
return (
url_path,
generate_api_reference_markdown_content(
Expand All @@ -586,12 +596,13 @@ def generate_class_api_reference_markdown(
),
fields=tuple(
(field.name, field.type_display, field.description or "")
for field in fields
for field in doc.fields
),
methods=tuple(
(method.name + method.signature, method.description or "")
for method in doc.methods
),
env_var_prefix=env_var_prefix,
),
)

Expand Down Expand Up @@ -654,7 +665,7 @@ def env_var_docstring(name: str) -> str:
"Reflex provides a number of environment variables that can be used to configure the behavior of your application.",
"These environment variables can be set in your shell environment or in a `.env` file.",
"",
"This page documents all available environment variables in Reflex.",
"This page documents the environment variables that are not config parameters. Environment variables that override `rx.Config` parameters (e.g. `REFLEX_FRONTEND_PORT`) are listed in the [config reference](/docs/api-reference/config/).",
"",
"## Environment Variables",
"",
Expand All @@ -676,13 +687,12 @@ def generate_dynamic_api_reference_files() -> tuple[tuple[Path, str], ...]:
import reflex as rx
from reflex.istate.manager import StateManager
from reflex.utils.imports import ImportVar
from reflex_docgen import generate_class_documentation

modules = [
rx.App,
rx.Component,
rx.ComponentState,
(rx.Config, rx.config.BaseConfig),
rx.Config,
rx.event.Event,
rx.event.EventHandler,
rx.event.EventSpec,
Expand All @@ -692,20 +702,18 @@ def generate_dynamic_api_reference_files() -> tuple[tuple[Path, str], ...]:
ImportVar,
rx.Var,
]
# Classes whose fields can be overridden via prefixed environment variables;
# the fields table gets an extra column listing each generated env var name.
env_var_prefixes = {rx.Config: "REFLEX_"}
files = []
for module in modules:
extra_fields: list[object] = []
if isinstance(module, tuple):
module, *extra_modules = module
for extra_module in extra_modules:
extra_fields.extend(generate_class_documentation(extra_module).fields)
slug = module.__name__.lower()
files.append(
generate_class_api_reference_markdown(
url_path=Path(f"api-reference/{slug}.md"),
title=_format_title(slug),
cls=module,
extra_fields=tuple(extra_fields),
env_var_prefix=env_var_prefixes.get(module),
)
)
files.append(generate_environment_variables_markdown())
Expand Down
17 changes: 6 additions & 11 deletions docs/app/reflex_docs/pages/docs/apiref.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import reflex as rx
from reflex.istate.manager import StateManager
from reflex.utils.imports import ImportVar
from reflex_docgen import generate_class_documentation

from reflex_docs.templates.docpage import docpage

Expand All @@ -11,7 +10,7 @@
rx.App,
rx.Component,
rx.ComponentState,
(rx.Config, rx.config.BaseConfig),
rx.Config,
rx.event.Event,
rx.event.EventHandler,
rx.event.EventSpec,
Expand All @@ -24,20 +23,16 @@
rx.Var,
]

# Classes whose fields can be overridden via prefixed environment variables;
# the fields table gets an extra column listing each generated env var name.
env_var_prefixes = {rx.Config: "REFLEX_"}

from .env_vars import env_vars_doc

pages = []
for module in modules:
if isinstance(module, tuple):
module, *extra_modules = module
extra_fields = ()
for extra_module in extra_modules:
extra_doc = generate_class_documentation(extra_module)
extra_fields = extra_fields + extra_doc.fields
else:
extra_fields = None
name = module.__name__.lower()
docs = generate_docs(name, module, extra_fields=extra_fields)
docs = generate_docs(name, module, env_var_prefix=env_var_prefixes.get(module))
title = name.replace("_", " ").title()
page_data = docpage(f"/api-reference/{name}/", title)(docs)
# Keep the short sidebar/nav label (e.g. "App"), but emit a descriptive HTML
Expand Down
4 changes: 1 addition & 3 deletions docs/app/reflex_docs/pages/docs/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -885,9 +885,7 @@ def component_docs(

return rx.box(
h2_comp(text=comp_display_name),
rx.box(
render_markdown(textwrap.dedent(doc.description or "")), class_name="pb-2"
),
rx.box(render_markdown(doc.description or ""), class_name="pb-2"),
props,
children,
triggers,
Expand Down
Loading
Loading