Skip to content

Commit 33165a2

Browse files
committed
docs(tutorial): add loading="lazy" to images
1 parent 7dd50ad commit 33165a2

File tree

1 file changed

+20
-20
lines changed

1 file changed

+20
-20
lines changed

docs/tutorials/address-book.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ export default function App() {
340340

341341
Now the child route should be rendering through the outlet.
342342

343-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/03.webp" />
343+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/03.webp" />
344344

345345
## Client Side Routing
346346

@@ -456,7 +456,7 @@ export default function App({ loaderData }) {
456456

457457
That's it! React Router will now automatically keep that data in sync with your UI. The sidebar should now look like this:
458458

459-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/04.webp" />
459+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/04.webp" />
460460

461461
You may be wondering why we're "client" loading data instead of loading the data on the server so we can do server-side rendering (SSR). Right now our contacts site is a [Single Page App][spa], so there's no server-side rendering. This makes it really easy to deploy to any static hosting provider, but we'll talk more about how to enable SSR in a bit so you can learn about all the different [rendering strategies][rendering-strategies] React Router offers.
462462

@@ -519,13 +519,13 @@ export function HydrateFallback() {
519519

520520
Now if you refresh the page, you'll briefly see the loading splash before the app is hydrated.
521521

522-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/05.webp" />
522+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/05.webp" />
523523

524524
## Index Routes
525525

526526
When you load the app and aren't yet on a contact page, you'll notice a big blank page on the right side of the list.
527527

528-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/06.webp" />
528+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/06.webp" />
529529

530530
When a route has children, and you're at the parent route's path, the `<Outlet>` has nothing to render because no children match. You can think of [index routes][index-route] as the default child route to fill in that space.
531531

@@ -565,7 +565,7 @@ export default function Home() {
565565
}
566566
```
567567

568-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/07.webp" />
568+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/07.webp" />
569569

570570
Voilà! No more blank space. It's common to put dashboards, stats, feeds, etc. at index routes. They can participate in data loading as well.
571571

@@ -661,7 +661,7 @@ export default function App() {
661661

662662
Now navigate to the [about page][about-page] and it should look like this:
663663

664-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/08.webp" />
664+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/08.webp" />
665665

666666
## Layout Routes
667667

@@ -798,7 +798,7 @@ export default function App() {
798798

799799
Now with that shuffling around done, our about page no longer loads contacts data nor is it nested inside of the sidebar layout:
800800

801-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/09.webp" />
801+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/09.webp" />
802802

803803
## Pre-rendering a Static Route
804804

@@ -865,7 +865,7 @@ Whether you set `ssr` to `true` or `false` depends on you and your users needs.
865865

866866
We should be seeing our old static contact page again, with one difference: the URL now has a real ID for the record.
867867

868-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/10.webp" />
868+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/10.webp" />
869869

870870
Remember the `:contactId` part of the route definition in `app/routes.ts`? These dynamic segments will match dynamic (changing) values in that position of the URL. We call these values in the URL "URL Params", or just "params" for short.
871871

@@ -898,7 +898,7 @@ export default function Contact({
898898
// existing code
899899
```
900900

901-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/11.webp" />
901+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/11.webp" />
902902

903903
## Throwing Responses
904904

@@ -934,7 +934,7 @@ Without client side routing, the browser will serialize the `form`'s data automa
934934

935935
We can test this out by clicking the "New" button in our app.
936936

937-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/12.webp" />
937+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/12.webp" />
938938

939939
React Router sends a 405 because there is no code on the server to handle this form navigation.
940940

@@ -959,7 +959,7 @@ export async function action() {
959959

960960
That's it! Go ahead and click the "New" button, and you should see a new record pop into the list 🥳
961961

962-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/13.webp" />
962+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/13.webp" />
963963

964964
The `createEmptyContact` method just creates an empty contact with no name or data or anything. But it does still create a record, promise!
965965

@@ -1081,7 +1081,7 @@ export default function EditContact({
10811081

10821082
Now click on your new record, then click the "Edit" button. We should see the new route.
10831083

1084-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/14.webp" />
1084+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/14.webp" />
10851085

10861086
## Updating Contacts with `FormData`
10871087

@@ -1110,7 +1110,7 @@ export async function action({
11101110

11111111
Fill out the form, hit save, and you should see something like this! <small>(Except easier on the eyes and maybe with the patience to cut watermelon.)</small>
11121112

1113-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/15.webp" />
1113+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/15.webp" />
11141114

11151115
## Mutation Discussion
11161116

@@ -1203,7 +1203,7 @@ export async function action() {
12031203

12041204
Now when we click "New", we should end up on the edit page:
12051205

1206-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/16.webp" />
1206+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/16.webp" />
12071207

12081208
## Active Link Styling
12091209

@@ -1253,7 +1253,7 @@ export default function SidebarLayout({
12531253

12541254
Note that we are passing a function to `className`. When the user is at the URL that matches `<NavLink to>`, then `isActive` will be true. When it's _about_ to be active (the data is still loading) then `isPending` will be true. This allows us to easily indicate where the user is and also provide immediate feedback when links are clicked but data needs to be loaded.
12551255

1256-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/17.webp" />
1256+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/17.webp" />
12571257

12581258
## Global Pending UI
12591259

@@ -1298,7 +1298,7 @@ export default function SidebarLayout({
12981298

12991299
In our case, we add a `"loading"` class to the main part of the app if we're not idle. The CSS then adds a nice fade after a short delay (to avoid flickering the UI for fast loads). You could do anything you want though, like show a spinner or loading bar across the top.
13001300

1301-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/18.webp" />
1301+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/18.webp" />
13021302

13031303
## Deleting Records
13041304

@@ -1448,7 +1448,7 @@ export async function loader({
14481448
// existing code
14491449
```
14501450

1451-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/19.webp" />
1451+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/19.webp" />
14521452

14531453
Because this is a `GET`, not a `POST`, React Router _does not_ call the `action` function. Submitting a `GET` `form` is the same as clicking a link: only the URL changes.
14541454

@@ -1766,13 +1766,13 @@ export default function SidebarLayout({
17661766

17671767
You should now have a nice spinner on the left side of the search input.
17681768

1769-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/20.webp" />
1769+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/20.webp" />
17701770

17711771
## Managing the History Stack
17721772

17731773
Since the form is submitted for every keystroke, typing the characters "alex" and then deleting them with backspace results in a huge history stack 😂. We definitely don't want this:
17741774

1775-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/21.webp" />
1775+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/21.webp" />
17761776

17771777
We can avoid this by _replacing_ the current entry in the history stack with the next page, instead of pushing into it.
17781778

@@ -1880,7 +1880,7 @@ export async function action({
18801880

18811881
Alright, we're ready to click the star next to the user's name!
18821882

1883-
<img class="tutorial" src="/_docs/v7_address_book_tutorial/22.webp" />
1883+
<img class="tutorial" loading="lazy" src="/_docs/v7_address_book_tutorial/22.webp" />
18841884

18851885
Check that out, both stars automatically update. Our new `<fetcher.Form method="post">` works almost exactly like the `<Form>` we've been using: it calls the action and then all data is revalidated automatically — even your errors will be caught the same way.
18861886

0 commit comments

Comments
 (0)