Skip to main content

ferro_inertia/
config.rs

1//! Configuration for Inertia.js integration.
2
3/// Configuration for Inertia.js responses.
4///
5/// # Example
6///
7/// ```rust
8/// use ferro_inertia::InertiaConfig;
9///
10/// // Development configuration (default)
11/// let config = InertiaConfig::default();
12///
13/// // Production configuration
14/// let config = InertiaConfig::new()
15///     .version("1.0.0")
16///     .production();
17///
18/// // Custom Vite dev server
19/// let config = InertiaConfig::new()
20///     .vite_dev_server("http://localhost:3000")
21///     .entry_point("src/app.tsx");
22/// ```
23#[derive(Debug, Clone)]
24pub struct InertiaConfig {
25    /// Vite dev server URL (e.g., "http://localhost:5173")
26    pub vite_dev_server: String,
27    /// Entry point for the frontend (e.g., "src/main.tsx")
28    pub entry_point: String,
29    /// Asset version for cache busting
30    pub version: String,
31    /// Whether we're in development mode (use Vite dev server)
32    pub development: bool,
33    /// Custom HTML template (if None, uses default)
34    pub html_template: Option<String>,
35    /// Path to Vite's manifest.json for resolving hashed asset filenames
36    pub manifest_path: String,
37}
38
39impl Default for InertiaConfig {
40    fn default() -> Self {
41        let vite_dev_server = std::env::var("VITE_DEV_SERVER")
42            .unwrap_or_else(|_| "http://localhost:5173".to_string());
43
44        let is_dev = !matches!(
45            std::env::var("APP_ENV").ok().as_deref(),
46            Some("production") | Some("staging")
47        );
48
49        Self {
50            vite_dev_server,
51            entry_point: "src/main.tsx".to_string(),
52            version: "1.0".to_string(),
53            development: is_dev,
54            html_template: None,
55            manifest_path: "public/assets/.vite/manifest.json".to_string(),
56        }
57    }
58}
59
60impl InertiaConfig {
61    /// Create a new configuration with default values.
62    pub fn new() -> Self {
63        Self::default()
64    }
65
66    /// Set the Vite dev server URL.
67    pub fn vite_dev_server(mut self, url: impl Into<String>) -> Self {
68        self.vite_dev_server = url.into();
69        self
70    }
71
72    /// Set the frontend entry point.
73    pub fn entry_point(mut self, entry: impl Into<String>) -> Self {
74        self.entry_point = entry.into();
75        self
76    }
77
78    /// Set the asset version for cache busting.
79    pub fn version(mut self, version: impl Into<String>) -> Self {
80        self.version = version.into();
81        self
82    }
83
84    /// Enable production mode (disables Vite dev server integration).
85    pub fn production(mut self) -> Self {
86        self.development = false;
87        self
88    }
89
90    /// Enable development mode (enables Vite dev server integration).
91    pub fn development(mut self) -> Self {
92        self.development = true;
93        self
94    }
95
96    /// Set the path to Vite's manifest.json.
97    pub fn manifest_path(mut self, path: impl Into<String>) -> Self {
98        self.manifest_path = path.into();
99        self
100    }
101
102    /// Set a custom HTML template.
103    ///
104    /// The template should contain the following placeholders:
105    /// - `{page}` - The escaped JSON page data
106    /// - `{csrf}` - The CSRF token (optional)
107    ///
108    /// # Example
109    ///
110    /// ```rust
111    /// use ferro_inertia::InertiaConfig;
112    ///
113    /// let template = r#"
114    /// <!DOCTYPE html>
115    /// <html>
116    /// <head><title>My App</title></head>
117    /// <body>
118    ///     <div id="app" data-page="{page}"></div>
119    ///     <script src="/app.js"></script>
120    /// </body>
121    /// </html>
122    /// "#;
123    ///
124    /// let config = InertiaConfig::new()
125    ///     .html_template(template);
126    /// ```
127    pub fn html_template(mut self, template: impl Into<String>) -> Self {
128        self.html_template = Some(template.into());
129        self
130    }
131}