Tauri HTTP Requests Tutorial - Build a Quote of the Day App | React + Rust
Video: Tauri HTTP Requests Tutorial - Build a Quote of the Day App | React + Rust by Taught by Celeste AI - AI Coding Coach
Watch full page →Tauri HTTP Requests Tutorial - Build a Quote of the Day App | React + Rust
In this tutorial, you’ll learn how to integrate HTTP requests into a Tauri desktop app using React and Rust. We build a Quote of the Day app that fetches random inspirational quotes from an external API, handling loading states, errors, and JSON parsing along the way.
Code
// src-tauri/src/main.rs
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
use tauri::{Builder};
use tauri_plugin_http::{Builder as HttpBuilder};
fn main() {
Builder::default()
// Enable HTTP plugin for making requests
.plugin(HttpBuilder::default().build())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
// src/App.tsx (React + TypeScript)
import React, { useState, useEffect } from 'react';
import { fetch } from '@tauri-apps/plugin-http';
interface Quote {
content: string;
author: string;
}
function App() {
const [quote, setQuote] = useState<Quote | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
async function fetchQuote() {
setLoading(true);
setError(null);
try {
// Fetch a random quote from dummyjson API
const response = await fetch('https://dummyjson.com/quotes/random');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setQuote({ content: data.quote, author: data.author });
} catch (err: any) {
setError(err.message || 'Failed to fetch quote');
} finally {
setLoading(false);
}
}
// Fetch a quote on component mount
useEffect(() => {
fetchQuote();
}, []);
return (
<div style={{ padding: 20, fontFamily: 'Arial, sans-serif', minHeight: '100vh', backgroundColor: '#121212', color: '#eee' }}>
<h1>Quote of the Day</h1>
{loading && <p>Loading...</p>}
{error && <p style={{ color: 'red' }}>Error: {error}</p>}
{quote && !loading && (
<div style={{ marginTop: 20, padding: 20, borderRadius: 8, backgroundColor: '#1e1e1e' }}>
<p style={{ fontStyle: 'italic', fontSize: 24 }}>"{quote.content}"</p>
<p style={{ marginTop: 10, fontSize: 18, color: '#888' }}>- {quote.author}</p>
</div>
)}
<button
onClick={fetchQuote}
disabled={loading}
style={{
marginTop: 30,
padding: '10px 20px',
fontSize: 16,
borderRadius: 5,
cursor: loading ? 'not-allowed' : 'pointer'
}}
>New Quote</button>
</div>
);
}
export default App;
// tauri.conf.json (excerpt showing HTTP permissions)
{
"tauri": {
"allowlist": {
"http": {
"all": true
}
},
"security": {
"csp": null
},
"plugins": {
"http": {
"scope": ["https://dummyjson.com"]
}
}
}
}
Key Points
- Use the tauri-plugin-http in Rust backend to enable HTTP requests securely.
- Configure explicit HTTP permissions in tauri.conf.json to allow network access only to trusted domains.
- Leverage the plugin’s fetch function in React to request external APIs and handle JSON responses.
- Manage loading and error states in React for a smooth user experience during asynchronous data fetching.
- Combine React’s useEffect hook with state hooks to fetch data on app startup and on demand.