ReferencesCloudflare WorkerRemix.RunCloudflare Worker - RemixCreate Project Cloudflare Worker + Remix.runTerminal windownpm create cloudflare@latest your-project -- --framework=remix --experimentalWrangler.tomlwrangler.tomlname = "your-project"compatibility_date = "2024-12-18" compatibility_flags = ["nodejs_compat_v2"]main = "./server.ts"assets = { directory = "./build/client" } # enabled log[observability]enabled = true # defined variables [vars]GITHUB_REPO = "namnh198/SecondBrain" CACHE_EXPIRED = 14400 DOMAIN = "namhoainguyen.com" ``` **P/S:** With Secret Environments, you should defined on `.dev.vars` ## KV Namespace ### Create KV Namespace ```shellnpx wrangler kv namespace create cacheDefined KV on wrangler.tomlwrangler.toml[[kv_namespaces]]binding = "cache"id = "kv_namespace_id"How to useroutes/_index.tsx1import type { LoaderFunctionArgs } from '@remix-run/cloudflare';2import { useLoaderData } from '@remix-run/react';3 4export const loader = async ({ context }: LoaderFunctionArgs) => {5 const cacheKey = 'test-cached';6 7 // get cached by cacheKey8 const cache = await context.cf.env.cache.get(cacheKey);9 if(cache) return JSON.parse(cache); // if cache exists return JSON cache10 const data = {"name": "Nam Hoai Nguyen", "text": "Hello World" }11 await context.cf.env.cache.put(cacheKey, JSON.stringify(data), {expirationTtl: 86400 }); // expired cached12 return data;13}14 15export default function Index () {16 const data = useLoaderData<typeof loader>();17 return (18 <ul>19 <li>{data.name}</li>20 <li>{data.text}</li>21 </ul>22 )23}LazyImagesInstall @unpic/reactTerminal windownpm install @unpic/reactCreate LazyImage Componentscomponents/lazy-image.tsx1import { useState, useEffect } from 'react';2import { type ImageProps as UnpicImageProps, Image as UnpicImage } from '@unpic/react';3 4export type ImageProps = UnpicImageProps & {5 isLoader?: boolean6};7 8export default function LazyImage(props: ImageProps) {9 const [loaded, setLoaded] = useState<boolean>(false);10 11 useEffect(() => {12 if(!props.isLoader) return;13 14 if (props.src) {15 const img = new Image();16 img.src = props.src;17 img.onload = () => {18 setLoaded(true);19 };20 }21 }, [props.src]);22 23 if (!loaded) {24 return (25 <span26 className={cn('inline-flex items-center justify-center animate-spin', props.className)}27 style={{ width: props.width || 'auto', height: props.height || 'auto' }}>28 <span>Loading...</span>29 </span>30 );31 }32 33 return <UnpicImage {...props} />;34}