pub(crate) fn render_to_string(
        &self,
        err: ServerErrorData,
        translator: Option<&Translator>,
    ) -> (String, String) {
        // We need to create an engine-side reactor
        let reactor =
            Reactor::<SsrNode>::engine(TemplateState::empty(), RenderMode::Error, translator);
        let mut body_str = String::new();
        let mut head_str = String::new();
        create_scope_immediate(|cx| {
            reactor.add_self_to_cx(cx);
            // Depending on whether or not we had a translator, we can figure out the
            // capabilities
            let err_cx = match translator {
                // On the engine-side, we don't get global state (see docs for
                // `ErrorContext::FullNoGlobal`)
                Some(_) => ErrorContext::FullNoGlobal,
                None => ErrorContext::WithReactor,
            };
            // NOTE: No hydration context
            let (head_view, body_view) = (self.handler)(
                cx,
                ClientError::ServerError {
                    status: err.status,
                    message: err.msg,
                },
                err_cx,
                ErrorPosition::Page,
            );

            head_str = sycamore::render_to_string(|_| with_no_hydration_context(|| head_view));
            body_str = sycamore::render_to_string(|_| body_view);
        });

        (head_str, body_str)
    }
Renders an error view on the engine-side. This takes an optional
translator. This will return a tuple of `String`ified views for the
head and body. For widget errors, the former should be discarded.

Since the only kind of error that can be sent from the server to the
client falls under a `ClientError::ServerError`, which always takes
up the whole page, and since we presumably don't have any actual
content to render, this will, expectedly, take up the whole page.

This cannot be used for widgets (use `.handle_widget()` instead).

# Hydration

At present, due to the difficulties of controlling hydration contexts
in a fine-grained manner, Perseus does not hydrate error views
whatsoever. This is compounded by the problem of exported error
views, which do not have access to locales, whereas their
browser-side-rendered counterparts do. To avoid hydration mismatches
and unnecessary development panics, hydration is therefore disabled
for error views.
packages/perseus/src/error_views.rs