T
TanStack11mo ago
rare-sapphire

Server functions not working with forms

The server function url seems to always be set to http://localhost:3000, so it works in dev, but not in production. Example from docs
import * as fs from 'fs'
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/start'

const filePath = 'count.txt'

async function readCount() {
return parseInt(
await fs.promises.readFile(filePath, 'utf-8').catch(() => '0'),
)
}

const getCount = createServerFn('GET', () => {
return readCount()
})

const updateCount = createServerFn('POST', async (formData: FormData) => {
const count = await readCount()
const addBy = Number(formData.get('addBy'))
await fs.promises.writeFile(filePath, `${count + addBy}`)
// Reload the page to trigger the loader again
return new Response('ok', { status: 301, headers: { Location: '/' } })
})

export const Route = createFileRoute('/')({
component: Home,
loader: async () => await getCount(),
})

function Home() {
const state = Route.useLoaderData()

return (
<div>
<form
action={updateCount.url}
method="POST"
encType="multipart/form-data"
>
<input type="number" name="addBy" defaultValue="1" />
<button type="submit">Add</button>
</form>
<pre>{state}</pre>
</div>
)
}
import * as fs from 'fs'
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/start'

const filePath = 'count.txt'

async function readCount() {
return parseInt(
await fs.promises.readFile(filePath, 'utf-8').catch(() => '0'),
)
}

const getCount = createServerFn('GET', () => {
return readCount()
})

const updateCount = createServerFn('POST', async (formData: FormData) => {
const count = await readCount()
const addBy = Number(formData.get('addBy'))
await fs.promises.writeFile(filePath, `${count + addBy}`)
// Reload the page to trigger the loader again
return new Response('ok', { status: 301, headers: { Location: '/' } })
})

export const Route = createFileRoute('/')({
component: Home,
loader: async () => await getCount(),
})

function Home() {
const state = Route.useLoaderData()

return (
<div>
<form
action={updateCount.url}
method="POST"
encType="multipart/form-data"
>
<input type="number" name="addBy" defaultValue="1" />
<button type="submit">Add</button>
</form>
<pre>{state}</pre>
</div>
)
}
1 Reply
passive-yellow
passive-yellow11mo ago
Hi, I see that using updateCount.url is meant to be used for progressive enhancement https://tanstack.com/router/latest/docs/framework/react/start/server-functions#no-js-server-functions Despite that the code to handle it is hardcoding localhost:3000, I've opened a issue https://github.com/TanStack/router/issues/2720 In your case you are expected to call the server function in one of these ways I guess
No description

Did you find this page helpful?