Skip to main content

Crate leptos_ntex_unofficial

Crate leptos_ntex_unofficial 

Source
Expand description

§leptos-ntex-unofficial

Crates.io docs.rs License

Unofficial SSR integration that lets you run a Leptos application on top of the ntex web framework.

This is a community adapter. It is not affiliated with the Leptos project or the ntex project. The officially-maintained adapters live in the Leptos monorepo as leptos_actix and leptos_axum. This crate takes leptos_actix as its starting point and ports the public API to ntex.

§Quick start

Add the dependency:

[dependencies]
leptos = { version = "0.8", features = ["ssr", "nonce"] }
leptos-ntex-unofficial = "0.4"
ntex = "3"

Define an App, a shell, and wire them up through register_leptos_routes:

use leptos::prelude::*;
use leptos_meta::{MetaTags, provide_meta_context};
use leptos_ntex_unofficial::{generate_route_list, register_leptos_routes};
use leptos_router::{components::{Route, Router, Routes}, path};
use ntex::web::{self, App as NtexApp};

#[component]
fn App() -> impl IntoView {
    provide_meta_context();
    view! {
        <Router>
            <Routes fallback=|| view! { <h1>"Not Found"</h1> }>
                <Route path=path!("/") view=|| view! { <h1>"Hello, ntex!"</h1> }/>
            </Routes>
        </Router>
    }
}

fn shell() -> impl IntoView {
    view! {
        <!DOCTYPE html>
        <html><head><MetaTags/></head><body><App/></body></html>
    }
}

#[ntex::main]
async fn main() -> std::io::Result<()> {
    let routes = generate_route_list(App);
    web::server(move || {
        let routes = routes.clone();
        async move {
            NtexApp::new().configure(move |cfg| {
                register_leptos_routes(cfg, routes.clone(), shell);
            })
        }
    })
    .bind(("127.0.0.1", 3000))?
    .run()
    .await
}

A runnable version of the same example is in examples/basic.rs — try it with:

cargo run --example basic

Most applications want three ntex registrations:

  1. app state containing LeptosOptions;
  2. a static bundle service for site_pkg_dir;
  3. generated Leptos routes plus a final file/404 fallback.
use leptos::{config::LeptosOptions, prelude::*};
use leptos_ntex_unofficial::{
    file_and_error_handler, register_leptos_routes, site_pkg_dir_service,
    LeptosServerFnConfig, NtexRouteListing,
};
use ntex::web::App as NtexApp;

let _app = NtexApp::new()
    .state(options.clone())
    .state(
        LeptosServerFnConfig::new()
            .with_payload_limit(8 * 1024 * 1024)
            .with_ws_channel_buffer(512),
    )
    .service(site_pkg_dir_service::<ntex::web::DefaultError>(&options))
    .configure(move |cfg| {
        register_leptos_routes(cfg, routes.clone(), app);
    })
    .route(
        "/{tail:.*}",
        file_and_error_handler::<_, ntex::web::DefaultError>(shell),
    );

site_pkg_dir_service is intended for generated assets such as JS, WASM, CSS, and their precompressed .br / .gz siblings. file_and_error_handler is the catch-all fallback: it first serves a safe file hit from site_root, then renders the Leptos shell with 404 Not Found when no file exists.

§Public API at a glance

ItemPurpose
generate_route_list(app_fn)Enumerate Leptos routes for registration
generate_route_list_with_ssgSame, also returns a static-site generator
LeptosRoutes::leptos_routesExtension trait on ntex::web::App to mount routes
register_leptos_routesServiceConfig-style alternative for composable setup
handle_server_fnsReturns a Route that dispatches all registered server functions
file_and_error_handlerServes files from site_root and falls back to a shell on 404
site_pkg_dir_serviceServes cargo-leptos-produced JS/WASM/CSS bundle, including .br/.gz siblings
NtexServerFnBackendUse as server = leptos_ntex_unofficial::NtexServerFnBackend on #[server]
extract, extract_with_errExtract ntex extractors (e.g. HttpRequest) from a server function
redirect(path)Issue a redirect from inside a server function
ResponseOptionsMutate response headers/status from inside a server function
LeptosServerFnConfigConfigure payload limit, WebSocket buffer, WS subprotocol
try_init_executorEagerly install the ntex-backed Leptos executor
register_explicitManually register server functions when inventory is unavailable
server_fn_paths, get_server_fn_serviceAdvanced hooks for custom server-fn routing

See the API docs for the full list, signatures, and runnable snippets.

§Feature flags

FeatureEffect
tracingEmit tracing spans around route rendering and server-fn dispatch
islands-routerForwards to leptos/islands-router

Nothing is enabled by default.

§Configuring server-fn limits

LeptosServerFnConfig is read out of ntex application state at request time:

use leptos_ntex_unofficial::{handle_server_fns, LeptosServerFnConfig};
use ntex::web::App as NtexApp;

let _app = NtexApp::new()
    .state(
        LeptosServerFnConfig::new()
            .with_payload_limit(8 * 1024 * 1024) // 8 MiB
            .with_ws_channel_buffer(512)
            .with_ws_subprotocol("graphql-ws"),
    )
    .route("/api/{tail:.*}", handle_server_fns());

If you don’t register a LeptosServerFnConfig, the defaults from DEFAULT_PAYLOAD_LIMIT and DEFAULT_WS_CHANNEL_BUFFER are used.

Configured WebSocket subprotocols are only echoed when the client offered the same protocol in Sec-WebSocket-Protocol. For dynamic negotiation, use a custom ntex WebSocket handler and ntex::web::ws::subprotocols.

§Proxy headers

ntex’s ConnectionInfo trusts Forwarded, X-Forwarded-Host, and X-Forwarded-Proto when resolving the request host and scheme. If the application runs behind a reverse proxy, configure the proxy to strip any client-supplied forwarding headers and set trusted values itself before the request reaches ntex. This matters for same-origin decisions such as the HTML-form server-function referrer fallback.

§Development

The shortest local feedback loop is:

cargo fmt --all -- --check
cargo test
cargo test --all-features
cargo clippy --all-targets --all-features -- -D warnings
RUSTDOCFLAGS="-D warnings" cargo doc --all-features --no-deps

See CONTRIBUTING.md for the repository workflow and release checklist.

§Migrating from leptos_actix

The public API intentionally mirrors leptos_actix, so most code ports 1:1 by switching the crate name and the server = ... backend:

leptos_actixleptos-ntex-unofficial
use leptos_actix::{...}use leptos_ntex_unofficial::{...}
server = leptos_actix::ActixServerFnBackendserver = leptos_ntex_unofficial::NtexServerFnBackend
actix-web types (HttpRequest, HttpResponse)ntex::web::HttpRequest, ntex::web::HttpResponse
actix-files::Filesntex-files::NamedFile behind site_pkg_dir_service / file_and_error_handler

A detailed port log is kept in ACTIX_TO_NTEX_NOTES.md in the repository.

§License

Dual-licensed under either of

at your option.

§Contributing

Bug reports and pull requests are welcome at https://github.com/AlexeyMatskevich/leptos_ntex.

Unless explicitly stated otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Re-exports§

pub use config::DEFAULT_PAYLOAD_LIMIT;
pub use config::DEFAULT_WS_CHANNEL_BUFFER;
pub use config::LeptosServerFnConfig;
pub use extract::extract;
pub use extract::extract_with_err;
pub use files::file_and_error_handler;
pub use files::file_and_error_handler_with_context;
pub use files::site_pkg_dir_service;
pub use leptos_routes::LeptosRoutes;
pub use leptos_routes::register_leptos_routes;
pub use render::handle_response_inner;
pub use render::render_app_async;
pub use render::render_app_async_with_context;
pub use render::render_app_to_stream;
pub use render::render_app_to_stream_in_order;
pub use render::render_app_to_stream_in_order_with_context;
pub use render::render_app_to_stream_with_context;
pub use render::render_app_to_stream_with_context_and_replace_blocks;
pub use request::Request;
pub use response::PinnedHtmlStream;
pub use response::ResponseOptions;
pub use response::ResponseParts;
pub use response::redirect;
pub use routes::NtexRouteListing;
pub use routes::generate_route_list;
pub use routes::generate_route_list_with_exclusions;
pub use routes::generate_route_list_with_exclusions_and_ssg;
pub use routes::generate_route_list_with_exclusions_and_ssg_and_context;
pub use routes::generate_route_list_with_ssg;
pub use routes::try_init_executor;
pub use server_fn::NtexExecutor;
pub use server_fn::NtexRequest;
pub use server_fn::NtexServerFnBackend;
pub use server_fn::NtexServerResponse;
pub use server_fn::generate_request_and_parts;
pub use server_fn::get_server_fn_service;
pub use server_fn::handle_server_fns;
pub use server_fn::handle_server_fns_with_context;
pub use server_fn::register_explicit;
pub use server_fn::server_fn_paths;
pub use static_routes::StaticRouteGenerator;

Modules§

config
Configuration knobs for the server-function dispatcher and helpers that enforce payload limits for non-streaming request bodies.
extract
Helpers for running FromRequest extractors inside a server function.
files
Static file serving: the site_pkg_dir service plus the file_and_error_handler fallback route.
leptos_routes
The LeptosRoutes trait and its two implementations for ntex’s App and [&mut ServiceConfig], plus the register_leptos_routes convenience wrapper.
render
SSR pipeline: request-to-HTML rendering helpers.
request
The Request wrapper that makes an ntex HttpRequest storable in Leptos’s Send/Sync reactive context.
response
HTTP response types and the redirect helper.
routes
Route-list generation and executor initialization.
server_fn
Ntex-backed server-function runtime.
static_routes
Static (SSG) route generation and the internal catch-all route used by LeptosRoutes.