dioxus_static_site_generation/
config.rs

1//! Launch helper macros for fullstack apps
2
3use std::path::PathBuf;
4
5use dioxus_lib::prelude::dioxus_core::LaunchConfig;
6
7/// Settings for a statically generated site that may be hydrated in the browser
8pub struct Config {
9    #[cfg(feature = "server")]
10    pub(crate) output_dir: PathBuf,
11
12    #[cfg(feature = "server")]
13    pub(crate) index_html: Option<String>,
14
15    #[cfg(feature = "server")]
16    pub(crate) index_path: Option<PathBuf>,
17
18    #[cfg(feature = "server")]
19    #[allow(clippy::type_complexity)]
20    pub(crate) map_path: Option<Box<dyn Fn(&str) -> PathBuf + Send + Sync + 'static>>,
21
22    #[cfg(feature = "server")]
23    pub(crate) root_id: Option<&'static str>,
24
25    #[cfg(feature = "server")]
26    pub(crate) additional_routes: Vec<String>,
27
28    #[cfg(feature = "server")]
29    pub(crate) github_pages: bool,
30}
31
32impl LaunchConfig for Config {}
33
34#[allow(clippy::derivable_impls)]
35impl Default for Config {
36    fn default() -> Self {
37        Self {
38            #[cfg(feature = "server")]
39            output_dir: PathBuf::from("./static"),
40            #[cfg(feature = "server")]
41            index_html: None,
42            #[cfg(feature = "server")]
43            index_path: None,
44            #[cfg(feature = "server")]
45            map_path: None,
46            #[cfg(feature = "server")]
47            root_id: None,
48            #[cfg(feature = "server")]
49            additional_routes: vec!["/".to_string()],
50            #[cfg(feature = "server")]
51            github_pages: false,
52        }
53    }
54}
55
56// Note: This config intentionally leaves server options in even if the server feature is not enabled to make it easier to use the config without moving different parts of the builder under configs.
57impl Config {
58    /// Create a new config for a static site generation app.
59    pub fn new() -> Self {
60        Self::default()
61    }
62
63    /// Set a mapping from the route to the file path. This will override the default mapping configured with `static_dir`.
64    /// The function should return the path to the folder to store the index.html file in.
65    ///
66    /// This method will only effect static site generation.
67    #[allow(unused)]
68    pub fn map_path<F: Fn(&str) -> PathBuf + Send + Sync + 'static>(mut self, map_path: F) -> Self {
69        #[cfg(feature = "server")]
70        {
71            self.map_path = Some(Box::new(map_path));
72        }
73        self
74    }
75
76    /// Set the output directory for the static site generation. (defaults to ./static)
77    /// This is the directory that will be used to store the generated static html files.
78    ///
79    /// This method will only effect static site generation.
80    #[allow(unused)]
81    pub fn output_dir(mut self, output_dir: PathBuf) -> Self {
82        #[cfg(feature = "server")]
83        {
84            self.output_dir = output_dir;
85        }
86        self
87    }
88
89    /// Set the id of the root element in the index.html file to place the prerendered content into. (defaults to main)
90    #[allow(unused)]
91    pub fn root_id(mut self, root_id: &'static str) -> Self {
92        #[cfg(feature = "server")]
93        {
94            self.root_id = Some(root_id);
95        }
96        self
97    }
98
99    /// Set the contents of the index.html file to be served. (precedence over index_path)
100    ///
101    /// This method will only effect static site generation.
102    #[allow(unused)]
103    pub fn index_html(mut self, index_html: String) -> Self {
104        #[cfg(feature = "server")]
105        {
106            self.index_html = Some(index_html);
107        }
108        self
109    }
110
111    /// Set the path of the index.html file to be served. (defaults to {assets_path}/index.html)
112    ///
113    /// This method will only effect static site generation.
114    #[allow(unused)]
115    pub fn index_path(mut self, index_path: PathBuf) -> Self {
116        #[cfg(feature = "server")]
117        {
118            self.index_path = Some(index_path);
119        }
120        self
121    }
122
123    /// Sets a list of static routes that will be pre-rendered and served in addition to the static routes in the router.
124    #[allow(unused)]
125    pub fn additional_routes(mut self, mut routes: Vec<String>) -> Self {
126        #[cfg(feature = "server")]
127        {
128            self.additional_routes.append(&mut routes);
129        }
130        self
131    }
132
133    /// A preset for github pages. This will output your files in the `/docs` directory and set up a `404.html` file.
134    pub fn github_pages(self) -> Self {
135        #[allow(unused_mut)]
136        let mut myself = self
137            .additional_routes(vec!["/404".into()])
138            .output_dir(PathBuf::from("./docs"));
139        #[cfg(feature = "server")]
140        {
141            myself.github_pages = true;
142        }
143        myself
144    }
145}
146
147#[cfg(feature = "server")]
148impl Config {
149    pub(crate) fn fullstack_template(&self) -> dioxus_fullstack::prelude::FullstackHTMLTemplate {
150        use dioxus_fullstack::prelude::{FullstackHTMLTemplate, ServeConfig};
151        let mut cfg_builder = ServeConfig::builder();
152        if let Some(index_html) = &self.index_html {
153            cfg_builder = cfg_builder.index_html(index_html.clone());
154        }
155        if let Some(index_path) = &self.index_path {
156            cfg_builder = cfg_builder.index_path(index_path.clone());
157        }
158        if let Some(root_id) = self.root_id {
159            cfg_builder = cfg_builder.root_id(root_id);
160        }
161        let cfg = cfg_builder.build();
162
163        FullstackHTMLTemplate::new(&cfg.unwrap())
164    }
165
166    pub(crate) fn create_cache(&mut self) -> dioxus_isrg::IncrementalRenderer {
167        let mut builder =
168            dioxus_isrg::IncrementalRenderer::builder().static_dir(self.output_dir.clone());
169        if let Some(map_path) = self.map_path.take() {
170            builder = builder.map_path(map_path);
171        }
172        builder.build()
173    }
174
175    pub(crate) fn create_renderer(&mut self) -> dioxus_ssr::Renderer {
176        let mut renderer = dioxus_ssr::Renderer::new();
177        renderer.pre_render = true;
178        renderer
179    }
180}