Skip to content

Commit 52d492b

Browse files
committed
Update the-protocol.mdx
1 parent 01c2ca4 commit 52d492b

File tree

1 file changed

+230
-1
lines changed

1 file changed

+230
-1
lines changed

v1/core-concepts/the-protocol.mdx

Lines changed: 230 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,233 @@ This page contains a detailed specification of the Inertia protocol. Be sure to
1010

1111
The very first request to an Inertia app is just a regular, full-page browser request, with no special Inertia headers or data. For these requests, the server returns a full HTML document.
1212

13-
{/* This HTML response includes the site assets (CSS, JavaScript) as well as a root `<div>` in the page's body. The root `<div>` serves as a mounting point for the client-side app, and includes adata-page attribute with a JSON encoded <a href="#the-page-object">page object</a> for the initialpage. Inertia uses this information to boot your client-side framework and display the initial page component.<div classname="overflow-hidden rounded"><div classname="px-6 pt-6 font-mono text-sm text-white"><div classname="text-xs font-bold uppercase text-gray-600">Request</div><div classname="mt-1"><span classname="text-blue-400">GET:</span> http://example.com/events/80</div><div><span classname="text-blue-400">Accept:</span> text/html, application/xhtml+xml</div><div classname="mt-8 text-xs font-bold uppercase text-gray-600">Response</div><div classname="mt-1">HTTP/1.1 200 OK</div><div><span classname="text-blue-400">Content-Type:</span> text/html; charset=utf-8</div></div><p><codeblock>mT5keZcVVw</codeblock></p><p><codeblock>tGbPYOhrQq</codeblock></p><p><codeblock>73mMeawQzt</codeblock></p></div></div></div>` */}
13+
This HTML response includes the site assets (CSS, JavaScript) as well as a root `<div>` in the
14+
page's body. The root `<div>` serves as a mounting point for the client-side app, and includes a
15+
`data-page` attribute with a JSON encoded <a href="#the-page-object">page object</a> for the initial
16+
page. Inertia uses this information to boot your client-side framework and display the initial page component.
17+
18+
<div className="overflow-hidden rounded" style={{ background: '#202e59' }}>
19+
<div className="px-6 pt-6 font-mono text-sm text-white">
20+
<div className="text-xs font-bold uppercase text-gray-600">Request</div>
21+
<div className="mt-1">
22+
<span className="text-blue-400">GET:</span> http://example.com/events/80
23+
</div>
24+
<div>
25+
<span className="text-blue-400">Accept:</span> text/html, application/xhtml+xml
26+
</div>
27+
<div className="mt-8 text-xs font-bold uppercase text-gray-600">Response</div>
28+
<div className="mt-1">HTTP/1.1 200 OK</div>
29+
<div>
30+
<span className="text-blue-400">Content-Type:</span> text/html; charset=utf-8
31+
</div>
32+
</div>
33+
```html
34+
<html>
35+
<head>
36+
<title>My app</title>
37+
<link href="/css/app.css" rel="stylesheet">
38+
<script src="/js/app.js" defer></script>
39+
</head>
40+
<body>
41+
<div id="app" data-page='{"component":"Event","props":{"event":{"id":80,"title":"Birthday party","start_date":"2019-06-02","description":"Come out and celebrate Jonathan&apos;s 36th birthday party!"}},"url":"/events/80","version":"c32b8e4965f418ad16eaebba1d4e960f"}'></div>
42+
</body>
43+
</html>
44+
```
45+
</div>
46+
47+
<Info>
48+
While the initial response is HTML, Inertia does not server-side render the JavaScript page components.
49+
</Info>
50+
51+
## Inertia responses
52+
53+
Once the Inertia app has been booted, all subsequent requests to the site are made via XHR with a
54+
`X-Inertia` header set to `true`. This header indicates that the request is being made by
55+
Inertia and isn't a standard full-page visit.
56+
57+
When the server detects the `X-Inertia` header, instead of responding with a full HTML document, it
58+
returns a JSON response with an encoded <a href="#the-page-object">page object</a>.
59+
60+
61+
<div className="overflow-hidden rounded" style={{ background: '#202e59' }}>
62+
<div className="px-6 pt-6 font-mono text-sm text-white">
63+
<div className="text-xs font-bold uppercase text-gray-600">Request</div>
64+
<div className="mt-1">
65+
<span className="text-blue-400">GET:</span> http://example.com/events/80
66+
</div>
67+
<div>
68+
<span className="text-blue-400">Accept:</span> text/html, application/xhtml+xml
69+
</div>
70+
<div>
71+
<span className="text-blue-400">X-Requested-With:</span> XMLHttpRequest
72+
</div>
73+
<div>
74+
<span className="text-blue-400">X-Inertia:</span> true
75+
</div>
76+
<div>
77+
<span className="text-blue-400">X-Inertia-Version:</span> 6b16b94d7c51cbe5b1fa42aac98241d5
78+
</div>
79+
<div className="mt-8 text-xs font-bold uppercase text-gray-600">Response</div>
80+
<div className="mt-1">HTTP/1.1 200 OK</div>
81+
<div>
82+
<span className="text-blue-400">Content-Type:</span> application/json
83+
</div>
84+
<div>
85+
<span className="text-blue-400">Vary:</span> X-Inertia
86+
</div>
87+
<div>
88+
<span className="text-blue-400">X-Inertia:</span> true
89+
</div>
90+
</div>
91+
```json
92+
{
93+
"component": "Event",
94+
"props": {
95+
"event": {
96+
"id": 80,
97+
"title": "Birthday party",
98+
"start_date": "2019-06-02",
99+
"description": "Come out and celebrate Jonathan's 36th birthday party!"
100+
}
101+
},
102+
"url": "/events/80",
103+
"version": "c32b8e4965f418ad16eaebba1d4e960f"
104+
}
105+
```
106+
</div>
107+
108+
109+
## The page object
110+
111+
Inertia shares data between the server and client via a page object. This object includes the necessary
112+
information required to render the page component, update the browser's history state, and track the site's
113+
asset version. The page object includes the following four properties:
114+
115+
- **component:** The name of the JavaScript page component.
116+
- **props:** The page props (data).
117+
- **url:** The page URL.
118+
- **version:** The current asset version.
119+
120+
On standard full page visits, the page object is JSON encoded into the `data-page` attribute in the
121+
root `<div>`. On Inertia visits, the page object is returned as the JSON payload.
122+
123+
## Asset versioning
124+
125+
126+
One common challenge with single-page apps is refreshing site assets when they've been changed. Inertia makes
127+
this easy by optionally tracking the current version of the site's assets. In the event that an asset changes,
128+
Inertia will automatically make a full-page visit instead of an XHR visit.
129+
130+
131+
The Inertia <a href="#the-page-object">page object</a> includes a `version` identifier. This version
132+
identifier is set server-side and can be a number, string, file hash, or any other value that represents the
133+
current "version" of your site's assets, as long as the value changes when the site's assets have been updated.
134+
135+
136+
Whenever an Inertia request is made, Inertia will include the current asset version in the
137+
`X-Inertia-Version` header. When the server receives the request, it compares the asset version
138+
provided in the `X-Inertia-Version` header with the current asset version. This is typically handled
139+
in the middleware layer of your server-side framework.
140+
141+
142+
If the asset versions are the same, the request simply continues as expected. However, if the asset versions are
143+
different, the server immediately returns a `409 Conflict` response, and includes the URL in a
144+
`X-Inertia-Location` header. This header is necessary, since server-side redirects may have occurred.
145+
This tells Inertia what the final intended destination URL is.
146+
147+
148+
Note, `409 Conflict` responses are only sent for `GET` requests, and not for
149+
`POST/PUT/PATCH/DELETE` requests. That said, they will be sent in the event that a `GET`
150+
redirect occurs after one of these requests.
151+
152+
153+
If "flash" session data exists when a `409 Conflict` response occurs, Inertia's server-side framework
154+
adapters will automatically reflash this data.
155+
156+
<div className="overflow-hidden rounded" style={{ background: '#202e59' }}>
157+
<div className="p-6 font-mono text-sm text-white">
158+
<div className="text-xs font-bold uppercase text-gray-600">Request</div>
159+
<div className="mt-1">
160+
<span className="text-blue-400">GET:</span> http://example.com/events/80
161+
</div>
162+
<div>
163+
<span className="text-blue-400">Accept:</span> text/html, application/xhtml+xml
164+
</div>
165+
<div>
166+
<span className="text-blue-400">X-Requested-With:</span> XMLHttpRequest
167+
</div>
168+
<div>
169+
<span className="text-blue-400">X-Inertia:</span> true
170+
</div>
171+
<div>
172+
<span className="text-blue-400">X-Inertia-Version:</span> 6b16b94d7c51cbe5b1fa42aac98241d5
173+
</div>
174+
<div className="mt-8 text-xs font-bold uppercase text-gray-600">Response</div>
175+
<div className="mt-1">409: Conflict</div>
176+
<div>
177+
<span className="text-blue-400">X-Inertia-Location:</span> http://example.com/events/80
178+
</div>
179+
</div>
180+
</div>
181+
182+
## Partial reloads
183+
184+
When making Inertia requests, the partial reload option allows you to request a subset of the props (data) from
185+
the server on subsequent visits to the _same_ page component. This can be a helpful performance
186+
optimization if it's acceptable that some page data becomes stale.
187+
188+
When a partial reload request is made, Inertia includes two additional headers with the request:
189+
`X-Inertia-Partial-Data` and `X-Inertia-Partial-Component`.
190+
191+
The `X-Inertia-Partial-Data` header is a comma separated list of the desired props (data) keys that
192+
should be returned.
193+
194+
The `X-Inertia-Partial-Component` header includes the name of the component that is being partially
195+
reloaded. This is necessary, since partial reloads only work for requests made to the same page component. If
196+
the final destination is different for some reason (eg. the user was logged out and is now on the login page),
197+
then no partial reloading will occur.
198+
199+
200+
<div className="overflow-hidden rounded" style={{ background: '#202e59' }}>
201+
<div className="px-6 pt-6 font-mono text-sm text-white">
202+
<div className="text-xs font-bold uppercase text-gray-600">Request</div>
203+
<div className="mt-1">
204+
<span className="text-blue-400">GET:</span> http://example.com/events
205+
</div>
206+
<div>
207+
<span className="text-blue-400">Accept:</span> text/html, application/xhtml+xml
208+
</div>
209+
<div>
210+
<span className="text-blue-400">X-Requested-With:</span> XMLHttpRequest
211+
</div>
212+
<div>
213+
<span className="text-blue-400">X-Inertia:</span> true
214+
</div>
215+
<div>
216+
<span className="text-blue-400">X-Inertia-Version:</span> 6b16b94d7c51cbe5b1fa42aac98241d5
217+
</div>
218+
<div>
219+
<span className="text-blue-400">X-Inertia-Partial-Data:</span> events
220+
</div>
221+
<div>
222+
<span className="text-blue-400">X-Inertia-Partial-Component:</span> Events
223+
</div>
224+
<div className="mt-8 text-xs font-bold uppercase text-gray-600">Response</div>
225+
<div className="mt-1">HTTP/1.1 200 OK</div>
226+
<div>
227+
<span className="text-blue-400">Content-Type:</span> application/json
228+
</div>
229+
</div>
230+
```json
231+
{
232+
"component": "Events",
233+
"props": {
234+
"auth": {...}, // NOT included
235+
"categories": [...], // NOT included
236+
"events": [...] // included
237+
},
238+
"url": "/events/80",
239+
"version": "c32b8e4965f418ad16eaebba1d4e960f"
240+
}
241+
```
242+
</div>

0 commit comments

Comments
 (0)