FAQs

How to get LanguageIdentifier?

use fluent_templates::LanguageIdentifier;

Tip

fluent-templates also depends externally on fluent-bundle whichs provides utilities for parsing the Fluent syntax.

Use an expression to set the cookie attributes and will not be validated.

let attrs = "SameSite=Strict; MyCustomAttr=MyCustomValue;";
leptos_fluent! {
    cookie_attrs: attrs,
    // ...
};

How to get the fallback language

From fluent-templates v0.10 onwards can be obtained from your translations.

let fallback_language = expect_i18n().translations.get()[0].fallback();

tr! and move_tr! outside reactive graph

Outside the reactive ownership tree, mainly known as the reactive graph, we can't obtain the context of I18n using expect_context::<leptos_fluent::I18n>(), which is what tr! and move_tr! do internally. Instead, we can pass the context as first parameter to the macros:

let i18n = expect_i18n();

let translated_signal = move_tr!(i18n, "my-translation");

And some shortcuts cannot be used. Rewrite all the code that calls expect_context internally:

  • Use i18n.language.set(lang) instead of lang.activate().
  • Use lang == i18n.language.get() instead of lang.is_active().

On events, panics

For example, the next code panics when the <div> container is clicked:

#[component]
pub fn App() -> impl IntoView {
    view! {
        <Show when=|| true>
            <Child/>
        </Show>
    }
}

#[component]
pub fn Child() -> impl IntoView {
    view! {
        <div on:click=|_| {
            tr!("my-translation");
        }>"CLICK ME!"</div>
    }
}

With Leptos v0.7, whatever tr! macro used in the on: event will panic, but with Leptos v0.6, this outsiding of the ownership tree has been ignored from the majority of the cases as unintended behavior.

To avoid that, pass the i18n context as first parameter to tr! or move_tr!:

#[component]
pub fn App() -> impl IntoView {
    view! {
        <Show when=|| true>
            <Child/>
        </Show>
    }
}

#[component]
pub fn Child() -> impl IntoView {
    let i18n = expect_i18n();
    view! {
        <div on:click=|_| {
            tr!(i18n, "my-translation");
        }>"CLICK ME!"</div>
    }
}

Why examples don't use <For/> component?

Bug

There are some cases in which the <For/> component is not reproducible between SSR and hydrate modes leading to different renders, so decided to use a simple vector to not bring confusion to main examples.

In any case, the <For/> component is safe on CSR contexts and leptos_fluent::Language implement Hash and Eq traits to be able to be passed directly to keys properties trigerring reactivity depending on the current active language.

use leptos_fluent::{i18n, Language};

leptos::logging::warn!("[WARNING]: Not secure on SSR");
view! {
    <p>{move_tr!("select-a-language")}</p>
    <For
        each=move || i18n().languages
        key=|lang| *lang
        children=move |lang| render_language(lang)
    />
}

fn render_language(lang: &'static Language) -> impl IntoView { ... }

How to manage translations on server actions

The translations reside on the client side, so the I18n can not be accessed as context on server actions. Pass the translations as values if the bandwidth is not a problem or use your own statics on server side.

use leptos::prelude::*;
use leptos_fluent::{tr, Language};

/// Server action showing client-side translated message on console
#[server(ShowHelloWorld, "/api")]
pub async fn show_hello_world(
    translated_hello_world: String,
    language: String,
) -> Result<(), ServerFnError> {
    println!("{translated_hello_world} ({language})");
    Ok(())
}

fn render_language(lang: &'static Language) -> impl IntoView {
    // Call on click to server action with a client-side translated
    // "hello-world" message
    let on_click = move |_| {
        lang.activate();
        spawn_local(async {
            _ = show_hello_world(
                tr!("hello-world"),
                lang.name.to_string(),
            ).await;
        });
    };

    view! {
        <div>
            <label for=lang>{lang.name}</label>
            <input
                id=lang
                name="language"
                value=lang
                checked=lang.is_active()
                on:click=on_click
                type="radio"
            />
        </div>
    }
}

How to get values of leptos_fluent! macro at runtime?

Use provide_meta_context at the macro initialization and get them with the method I18n::meta:

leptos_fluent! {
    // ...
    provide_meta_context: true,
};

// ... later
println!("Macro parameters: {:?}", expect_i18n().meta().unwrap());

Configuration conditional checks

leptos_fluent! {
    // ...
    #[cfg(debug_assertions)]
    set_language_to_url_param: true,
    #[cfg(not(debug_assertions))]
    set_language_to_url_param: false,
}