| Crates.io | ferro-inertia |
| lib.rs | ferro-inertia |
| version | 0.1.71 |
| created_at | 2026-01-16 17:45:19.446154+00 |
| updated_at | 2026-01-17 20:05:08.776748+00 |
| description | Server-side Inertia.js adapter for Rust web frameworks |
| homepage | https://github.com/albertogferrario/ferro |
| repository | https://github.com/albertogferrario/ferro |
| max_upload_size | |
| id | 2049036 |
| size | 33,933 |
Server-side Inertia.js adapter for the Ferro framework.
X-Inertia-Partial-Data header[dependencies]
ferro-inertia = "0.1"
InertiaRequest traituse ferro_inertia::InertiaRequest;
impl InertiaRequest for MyRequest {
fn inertia_header(&self, name: &str) -> Option<&str> {
self.headers().get(name).and_then(|v| v.to_str().ok())
}
fn path(&self) -> &str {
self.uri().path()
}
}
use ferro_inertia::Inertia;
use serde_json::json;
async fn index(req: MyRequest) -> MyResponse {
let response = Inertia::render(&req, "Home", json!({
"title": "Welcome",
"user": {
"name": "John Doe",
"email": "john@example.com"
}
}));
// Convert InertiaHttpResponse to your framework's response type
response.into()
}
use ferro_inertia::{Inertia, InertiaShared};
async fn handler(req: MyRequest) -> MyResponse {
let shared = InertiaShared::new()
.auth(get_current_user())
.csrf(get_csrf_token())
.flash(get_flash_messages());
let response = Inertia::render_with_shared(&req, "Dashboard", props, &shared);
response.into()
}
use ferro_inertia::InertiaConfig;
// Development (default)
let config = InertiaConfig::new()
.vite_dev_server("http://localhost:5173")
.entry_point("src/main.tsx");
// Production
let config = InertiaConfig::new()
.version("1.0.0")
.production();
// Custom HTML template
let config = InertiaConfig::new()
.html_template(r#"
<!DOCTYPE html>
<html>
<head><title>My App</title></head>
<body>
<div id="app" data-page="{page}"></div>
<script src="/app.js"></script>
</body>
</html>
"#);
// In middleware, check for version mismatch
if let Some(conflict_response) = Inertia::check_version(&req, "1.0.0", "/") {
return conflict_response.into();
}
Partial reloads are handled automatically. When the client sends:
X-Inertia-Partial-Data: user,notifications
X-Inertia-Partial-Component: Dashboard
Only the requested props (user, notifications) will be included in the response.
use axum::{response::IntoResponse, http::StatusCode};
use ferro_inertia::InertiaHttpResponse;
impl IntoResponse for InertiaHttpResponse {
fn into_response(self) -> axum::response::Response {
let mut response = axum::response::Response::builder()
.status(StatusCode::from_u16(self.status).unwrap());
for (name, value) in self.headers {
response = response.header(name, value);
}
response
.header("Content-Type", self.content_type)
.body(self.body.into())
.unwrap()
}
}
use actix_web::HttpResponse;
use ferro_inertia::InertiaHttpResponse;
impl From<InertiaHttpResponse> for HttpResponse {
fn from(res: InertiaHttpResponse) -> Self {
let mut builder = HttpResponse::build(
actix_web::http::StatusCode::from_u16(res.status).unwrap()
);
for (name, value) in res.headers {
builder.insert_header((name, value));
}
builder
.content_type(res.content_type)
.body(res.body)
}
}
MIT License - see LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request.