From 86259837e26b8600adf64feafd289d4ece5492bd Mon Sep 17 00:00:00 2001 From: shrutikapoor08 Date: Tue, 18 Nov 2025 23:47:42 -0800 Subject: [PATCH 1/2] small fix to server function --- .../framework/react/fetching-external-api.md | 43 +++++++++++-------- .../framework/react/reading-writing-file.md | 2 +- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/docs/start/framework/react/fetching-external-api.md b/docs/start/framework/react/fetching-external-api.md index 16f49f6ce87..ee2352f3dc5 100644 --- a/docs/start/framework/react/fetching-external-api.md +++ b/docs/start/framework/react/fetching-external-api.md @@ -67,9 +67,9 @@ At this point, the project structure should look like this: ``` -Once your project is set up, you can access your app at localhost:3000. You should see the default TanStack Start welcome page. +Once your project is set up, you can access your app at `localhost:3000`. You should see the default TanStack Start welcome page. -## Step 1: Setup a .env file with TMDB_AUTH_TOKEN +## Step 1: Setup a `.env` file with TMDB_AUTH_TOKEN To fetch movies from the TMDB API, you need an authentication token. You can get this for free at themoviedb.org. @@ -114,37 +114,35 @@ export interface TMDBResponse { ``` ## Step 3: Creating the Route with API Fetch Function - -Now let's create our route that fetches data from the TMDB API. Create a new file at `src/routes/fetch-movies.tsx`: +To call the TMDB API, we're going to create a server function that fetches data on the server. This approach keeps our API credentials secure by never exposing them to the client. +Let's create our route that fetches data from the TMDB API. Create a new file at `src/routes/fetch-movies.tsx`: ```typescript // src/routes/fetch-movies.tsx import { createFileRoute } from '@tanstack/react-router' import type { Movie, TMDBResponse } from '../types/movie' +import { createServerFn } from '@tanstack/react-start' const API_URL = 'https://api.themoviedb.org/3/discover/movie?include_adult=false&include_video=false&language=en-US&page=1&sort_by=popularity.desc' -async function fetchPopularMovies(): Promise { - const token = process.env.TMDB_AUTH_TOKEN - if (!token) { - throw new Error('Missing TMDB_AUTH_TOKEN environment variable') - } - - const response = await fetch(API_URL, { - headers: { - accept: 'application/json', - Authorization: `Bearer ${token}`, - }, - }) +const fetchPopularMovies = createServerFn().handler(async (): Promise => { + const response = await fetch( + API_URL, + { + headers: { + 'accept': 'application/json', + 'Authorization': `Bearer ${process.env.TMDB_AUTH_TOKEN}`, + }, + } + ) if (!response.ok) { throw new Error(`Failed to fetch movies: ${response.statusText}`) } - const data = (await response.json()) as TMDBResponse - return data -} + return response.json() +}) export const Route = createFileRoute('/fetch-movies')({ component: MoviesPage, @@ -160,6 +158,13 @@ export const Route = createFileRoute('/fetch-movies')({ }) ``` +*What's happening here:* + +- `createServerFn()` creates a server-only function that runs exclusively on the server, ensuring our `TMDB_AUTH_TOKEN` environment variable never gets exposed to the client. The server function makes an authenticated request to the TMDB API and returns the parsed JSON response. +- The route loader runs on the server when a user visits /fetch-movies, calling our server function before the page renders +- Error handling ensures the component always receives valid data structure - either the movies or an empty array with an error message +- This pattern provides server-side rendering, automatic type safety, and secure API credential handling out of the box. + ## Step 4: Building the Movie Components Now let's create the components that will display our movie data. Add these components to the same `fetch-movies.tsx` file: diff --git a/docs/start/framework/react/reading-writing-file.md b/docs/start/framework/react/reading-writing-file.md index 3748dcca857..b67ab4ba787 100644 --- a/docs/start/framework/react/reading-writing-file.md +++ b/docs/start/framework/react/reading-writing-file.md @@ -3,7 +3,7 @@ id: reading-and-writing-file title: Building a Full Stack DevJokes App with TanStack Start --- -This tutorial will guide you through building a complete full-stack application using TanStack Start. You'll create a DevJokesapp where users can view and add developer-themed jokes, demonstrating key concepts of TanStack Start including server functions, file-based data storage, and React components. +This tutorial will guide you through building a complete full-stack application using TanStack Start. You'll create a DevJokes app where users can view and add developer-themed jokes, demonstrating key concepts of TanStack Start including server functions, file-based data storage, and React components. Here's a demo of the app in action: From 5fd09ee801bee82dda0e92efccd210ae7129af26 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 07:53:50 +0000 Subject: [PATCH 2/2] ci: apply automated fixes --- .../react/tutorial/fetching-external-api.md | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/start/framework/react/tutorial/fetching-external-api.md b/docs/start/framework/react/tutorial/fetching-external-api.md index 22a5439c241..57063d52c81 100644 --- a/docs/start/framework/react/tutorial/fetching-external-api.md +++ b/docs/start/framework/react/tutorial/fetching-external-api.md @@ -114,6 +114,7 @@ export interface TMDBResponse { ``` ## Step 3: Creating the Route with API Fetch Function + To call the TMDB API, we're going to create a server function that fetches data on the server. This approach keeps our API credentials secure by never exposing them to the client. Let's create our route that fetches data from the TMDB API. Create a new file at `src/routes/fetch-movies.tsx`: @@ -126,23 +127,22 @@ import { createServerFn } from '@tanstack/react-start' const API_URL = 'https://api.themoviedb.org/3/discover/movie?include_adult=false&include_video=false&language=en-US&page=1&sort_by=popularity.desc' -const fetchPopularMovies = createServerFn().handler(async (): Promise => { - const response = await fetch( - API_URL, - { +const fetchPopularMovies = createServerFn().handler( + async (): Promise => { + const response = await fetch(API_URL, { headers: { - 'accept': 'application/json', - 'Authorization': `Bearer ${process.env.TMDB_AUTH_TOKEN}`, + accept: 'application/json', + Authorization: `Bearer ${process.env.TMDB_AUTH_TOKEN}`, }, - } - ) + }) - if (!response.ok) { - throw new Error(`Failed to fetch movies: ${response.statusText}`) - } + if (!response.ok) { + throw new Error(`Failed to fetch movies: ${response.statusText}`) + } - return response.json() -}) + return response.json() + }, +) export const Route = createFileRoute('/fetch-movies')({ component: MoviesPage, @@ -158,7 +158,7 @@ export const Route = createFileRoute('/fetch-movies')({ }) ``` -*What's happening here:* +_What's happening here:_ - `createServerFn()` creates a server-only function that runs exclusively on the server, ensuring our `TMDB_AUTH_TOKEN` environment variable never gets exposed to the client. The server function makes an authenticated request to the TMDB API and returns the parsed JSON response. - The route loader runs on the server when a user visits /fetch-movies, calling our server function before the page renders