```jsx app/routes/realtime.jsx
import { useLoaderData, useOutletContext } from '@remix-run/react'
import { createServerClient } from '@supabase/auth-helpers-remix'
import { json } from '@remix-run/node'
import { useEffect, useState } from 'react'
export const loader = async ({ request }) => {
const response = new Response()
const supabase = createServerClient(process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY, {
request,
response,
})
const { data } = await supabase.from('posts').select()
return json({ serverPosts: data ?? [] }, { headers: response.headers })
}
export default function Index() {
const { serverPosts } = useLoaderData()
const [posts, setPosts] = useState(serverPosts)
const { supabase } = useOutletContext()
useEffect(() => {
setPosts(serverPosts)
}, [serverPosts])
useEffect(() => {
const channel = supabase
.channel('*')
.on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'posts' }, (payload) =>
setPosts([...posts, payload.new])
)
.subscribe()
return () => {
supabase.removeChannel(channel)
}
}, [supabase, posts, setPosts])
return {JSON.stringify(posts, null, 2)}
}
```