Progressive enhancement means making your web app work well for everyone, even if some features or scripts don't load. It helps users get the basic content and functions first, then adds extra features if possible.
Progressive enhancement in Remix
import { useLoaderData } from '@remix-run/react'; export function loader() { return { message: 'Hello from server!' }; } export default function Component() { const data = useLoaderData(); return ( <main> <h1>{data.message}</h1> <noscript> <p>Please enable JavaScript for a better experience.</p> </noscript> </main> ); }
The loader function runs on the server and sends data to the component.
The <noscript> tag shows content only if JavaScript is off.
import { useLoaderData } from '@remix-run/react'; export function loader() { return { greeting: 'Welcome!' }; } export default function Home() { const data = useLoaderData(); return <h1>{data.greeting}</h1>; }
<noscript> to provide fallback content for users without JavaScript.<noscript> <p>This message shows only if JavaScript is disabled.</p> </noscript>
import { useLoaderData } from '@remix-run/react'; export default function Component() { const data = useLoaderData(); return ( <> <h1>{data.message}</h1> <button onClick={() => alert('Clicked!')}>Click me</button> <noscript> <p>Enable JavaScript to use the button.</p> </noscript> </> ); }
This Remix component uses a server loader to send a message. It shows the message always. If JavaScript is off, the <noscript> message tells the user to enable it for more features.
import { useLoaderData } from '@remix-run/react'; export function loader() { return { message: 'Hello from Remix!' }; } export default function Greeting() { const data = useLoaderData(); return ( <main> <h1>{data.message}</h1> <noscript> <p>Please enable JavaScript to see interactive features.</p> </noscript> </main> ); }
Progressive enhancement helps your app work for everyone, no matter their device or settings.
Always provide meaningful content in the server loader so users see something useful without JavaScript.
Use <noscript> to gently guide users who have JavaScript disabled.
Progressive enhancement means building your app to work first with basic features, then adding extras.
Use Remix loaders to send server data that works without JavaScript.
Use <noscript> tags to show fallback messages for users without JavaScript.
Practice
Solution
Step 1: Understand progressive enhancement concept
Progressive enhancement means starting with a simple, working version of the app that works without JavaScript or advanced features.Step 2: Compare options to this concept
Make the app work with basic features first, then add extras matches this idea by focusing on basic features first, then adding extras. Other options rely on JavaScript or complex frameworks only.Final Answer:
Make the app work with basic features first, then add extras -> Option AQuick Check:
Progressive enhancement = basic first, then extras [OK]
- Thinking progressive enhancement means only using JavaScript
- Believing all data must load on client side
- Confusing with single-page app behavior
Solution
Step 1: Identify HTML tag for no-JavaScript fallback
The <noscript> tag is the standard HTML way to show content only when JavaScript is disabled.Step 2: Check other options for correctness
Options B, C, and D use invalid or non-standard tags or scripts that won't work as fallback content.Final Answer:
<noscript>Your browser needs JavaScript enabled.</noscript> -> Option DQuick Check:
Fallback for no JS = <noscript> [OK]
- Using custom or invalid tags for fallback
- Trying to detect JS with scripts inside fallback
- Not providing any fallback content
export async function loader() {
return { message: 'Hello from server' };
}
export default function Greeting() {
const data = useLoaderData();
return <div>{data.message}</div>;
}Solution
Step 1: Understand Remix loader and server rendering
The loader runs on the server and sends data to the component before rendering the page.Step 2: Consider no JavaScript scenario
Since Remix renders on the server, the user sees the server-rendered HTML with the message even if JavaScript is off.Final Answer:
The message 'Hello from server' is shown -> Option BQuick Check:
Server data shows without JS = message visible [OK]
- Assuming no output without JavaScript
- Confusing client-side hooks with server data
- Thinking loader runs only on client
export default function Page() {
React.useEffect(() => {
fetch('/api/data').then(res => res.json()).then(console.log);
}, []);
return <div>Loading...</div>;
}Solution
Step 1: Analyze data fetching method
The component fetches data only inside useEffect, which runs only in the browser after load.Step 2: Check progressive enhancement impact
Without JavaScript, useEffect never runs, so no data is fetched or shown, breaking progressive enhancement.Final Answer:
It does not fetch data on the server, so no content without JavaScript -> Option AQuick Check:
Client-only fetch breaks no-JS support [OK]
- Thinking useEffect runs on server
- Ignoring no-JS users
- Assuming fetch URL alone fixes enhancement
Solution
Step 1: Identify server-side data fetching
Fetching items in the loader ensures the list is rendered on the server and visible without JavaScript.Step 2: Add client-side filtering
Using useState and input events for filtering adds extra features for users with JavaScript, enhancing the experience.Step 3: Evaluate other options
The other options fail to show data server-side or rely only on client JS, breaking progressive enhancement.Final Answer:
Fetch items in the loader and render them server-side; add client filtering with useState and input events -> Option CQuick Check:
Server fetch + client filter = progressive enhancement [OK]
- Fetching data only on client side
- Not rendering initial data server-side
- Ignoring progressive enhancement principles
Ready to prove it?
Pass the test and this pattern moves unknown
