services/config/config.jsxjavascript
/*
Central place for app configuration values coming from two sources:
- .env variables (source: "env", read via import.meta.env)
- URL search params (source: "param", read via useSearchParams)
Adding a new config value should NOT require new hook logic. Just add one
entry to CONFIG_SCHEMA in config-schema.js - useConfig() reads and validates it generically
via parseConfigValue() (src/utils/validationFunctions.js).
No React Context/Provider here on purpose: import.meta.env is static and
useSearchParams() is already globally available via react-router, so a plain
hook is enough - no extra Provider needed in App.jsx.
Schema entry fields:
key - property name under which the parsed value is returned
source - "env" (import.meta.env) or "param" (URL search param)
name - the actual env var name (e.g. "VITE_...") or param name to read
type - "boolean" | "number" | "string", see parseConfigValue for parsing rules
default - fallback value if unset or invalid
min/max - optional bounds, "number" type only
description - human-readable explanation, for docs/debug UIs (not read by useConfig itself)
*/
import { useMemo } from "react";
import { useSearchParams } from "react-router";
import { CONFIG_SCHEMA } from "./config-schema";
import { parseConfigValue } from "../../utils/validationFunctions";
/**
* React hook that resolves every entry in CONFIG_SCHEMA (config-schema.js)
* against the current URL search params / import.meta.env and returns them
* as a flat, typed `{ key: value }` object.
*
* @returns {Object} Config values keyed by their CONFIG_SCHEMA `key`.
*/
export const useConfig = () => {
const [searchParams] = useSearchParams();
return useMemo(
() =>
CONFIG_SCHEMA.reduce((config, def) => {
const rawValue =
def.source === "param" ? searchParams.get(def.name) : import.meta.env[def.name];
config[def.key] = parseConfigValue(rawValue, def);
return config;
}, {}),
[searchParams]
);
};