-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
66 changed files
with
3,667 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,14 @@ | ||
# hotwire-native-demo | ||
Demo web server for the Hotwire Native frameworks | ||
# Hotwire Native Demo | ||
|
||
A small web app to demonstrate how to use Hotwire with the Hotwire Native frameworks. The demo app is available at [https://turbo-native-demo.glitch.me](https://turbo-native-demo.glitch.me) | ||
|
||
## Running Locally | ||
|
||
Clone the repo, and then: | ||
|
||
``` | ||
$ npm install | ||
$ npx nodemon | ||
``` | ||
|
||
The server is running on [`localhost:45678`](http://localhost:45678). You can open that url in the browser and ensure the native app is using the same url. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"subtitle": "Reference", | ||
"items": [ | ||
{ | ||
"id": 1, | ||
"title": "Turbo Drive", | ||
"description": "Turbo Drive accelerates links and form submissions by negating the need for full page reloads.", | ||
"path": "/reference/turbo-drive", | ||
"icon_path": "/images/turbo-drive.png" | ||
}, | ||
{ | ||
"id": 2, | ||
"title": "Turbo Frames", | ||
"description": "Turbo Frames decompose pages into independent contexts, which scope navigation and can be lazily loaded.", | ||
"path": "/reference/turbo-frames", | ||
"icon_path": "/images/turbo-frames.png" | ||
}, | ||
{ | ||
"id": 3, | ||
"title": "Turbo Streams", | ||
"description": "Turbo Streams deliver page changes over WebSocket, SSE or in response to form submissions using just HTML and a set of CRUD-like actions.", | ||
"path": "/reference/turbo-streams", | ||
"icon_path": "/images/turbo-streams.png" | ||
}, | ||
{ | ||
"id": 4, | ||
"title": "Turbo Native", | ||
"description": "Turbo Native lets your majestic monolith form the center of your native iOS and Android apps, with seamless transitions between web and native sections.", | ||
"path": "/reference/turbo-native", | ||
"icon_path": "/images/turbo-native.png" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"title": "Turbo Drive: Navigate within a persistent process", | ||
"content": "A key attraction with traditional single-page applications, when compared with the old-school, separate-pages approach, is the speed of navigation. SPAs get a lot of that speed from not constantly tearing down the application process, only to reinitialize it on the very next page.\n\nTurbo Drive gives you that same speed by using the same persistent-process model, but without requiring you to craft your entire application around the paradigm. There’s no client-side router to maintain, there’s no state to carefully manage. The persistent process is managed by Turbo, and you write your server-side code as though you were living back in the early aughts – blissfully isolated from the complexities of today’s SPA monstrosities!\n\nThis happens by intercepting all clicks on links to the same domain. When you click an eligible link, Turbo Drive prevents the browser from following it, changes the browser’s URL using the History API, requests the new page using fetch, and then renders the HTML response.\n\nSame deal with forms. Their submissions are turned into fetch requests from which Turbo Drive will follow the redirect and render the HTML response.\n\nDuring rendering, Turbo Drive replaces the current 'body' element outright and merges the contents of the 'head' element. The JavaScript window and document objects, and the 'html' element, persist from one rendering to the next.\n\nWhile it’s possible to interact directly with Turbo Drive to control how visits happen or hook into the lifecycle of the request, the majority of the time this is a drop-in replacement where the speed is free just by adopting a few conventions.", | ||
"icon_path": "/images/turbo-drive.png", | ||
"external_link": { | ||
"title": "Navigate with Turbo Drive", | ||
"url": "https://turbo.hotwired.dev/handbook/drive" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"title": "Turbo Frames: Decompose complex pages", | ||
"content": "Most web applications present pages that contain several independent segments. For a discussion page, you might have a navigation bar on the top, a list of messages in the center, a form at the bottom to add a new message, and a sidebar with related topics. Generating this discussion page normally means generating each segment in a serialized manner, piecing them all together, then delivering the result as a single HTML response to the browser.\n\nWith Turbo Frames, you can place those independent segments inside frame elements that can scope their navigation and be lazily loaded. Scoped navigation means all interaction within a frame, like clicking links or submitting forms, happens within that frame, keeping the rest of the page from changing or reloading.\n\nTurbo Frames affords you:\n\nEfficient caching. In the discussion page example above, the related topics sidebar needs to expire whenever a new related topic appears, but the list of messages in the center does not. When everything is just one page, the whole cache expires as soon as any of the individual segments do. With frames, each segment is cached independently, so you get longer-lived caches with fewer dependent keys.\n\nParallelized execution. Each defer-loaded frame is generated by its own HTTP request/response, which means it can be handled by a separate process. This allows for parallelized execution without having to manually manage the process. A complicated composite page that takes 400ms to complete end-to-end can be broken up with frames where the initial request might only take 50ms, and each of three defer-loaded frames each take 50ms. Now the whole page is done in 100ms because the three frames each taking 50ms run concurrently rather than sequentially.\n\nReady for mobile. In mobile apps, you usually can’t have big, complicated composite pages. Each segment needs a dedicated screen. With an application built using Turbo Frames, you’ve already done this work of turning the composite page into segments. These segments can then appear in native sheets and screens without alteration (since they all have independent URLs).", | ||
"icon_path": "/images/turbo-frames.png", | ||
"external_link": { | ||
"title": "Decompose with Turbo Frames", | ||
"url": "https://turbo.hotwired.dev/handbook/frames" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"title": "Turbo Native: Hybrid apps for iOS & Android", | ||
"content": "Turbo Native is ideal for building hybrid apps for iOS and Android. You can use your existing server-rendered HTML to get baseline coverage of your app’s functionality in a native wrapper. Then you can spend all the time you saved on making the few screens that really benefit from high-fidelity native controls even better.\n\nAn application like Basecamp has hundreds of screens. Rewriting every single one of those screens would be an enormous task with very little benefit. Better to reserve the native firepower for high-touch interactions that really demand the highest fidelity. Something like the “New For You” inbox in Basecamp, for example, where we use swipe controls that need to feel just right. But most pages, like the one showing a single message, wouldn’t really be any better if they were completely native.\n\nGoing hybrid doesn’t just speed up your development process, it also gives you more freedom to upgrade your app without going through the slow and onerous app store release processes. Anything that’s done in HTML can be changed in your web application, and instantly be available to all users. No waiting for Big Tech to approve your changes, no waiting for users to upgrade.\n\nTurbo Native assumes you’re using the recommended development practices available for iOS and Android. This is not a framework that abstracts native APIs away or even tries to let your native code be shareable between platforms. The part that’s shareable is the HTML that’s rendered server-side. But the native controls are written in the recommended native APIs.", | ||
"icon_path": "/images/turbo-native.png", | ||
"external_link": { | ||
"title": "Go Native on iOS & Android", | ||
"url": "https://turbo.hotwired.dev/handbook/native" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"title": "Turbo Streams: Deliver live page changes", | ||
"content": "Making partial page changes in response to asynchronous actions is how we make the application feel alive. While Turbo Frames give us such updates in response to direct interactions within a single frame, Turbo Streams let us change any part of the page in response to updates sent over a WebSocket connection, SSE or other transport. (Think an imbox that automatically updates when a new email arrives.)\n\nTurbo Streams introduces a 'turbo-stream' element with seven basic actions: append, prepend, replace, update, remove, before, and after. With these actions, along with the target attribute specifying the ID of the element you want to operate on, you can encode all the mutations needed to refresh the page. You can even combine several stream elements in a single stream message. Simply include the HTML you’re interested in inserting or replacing in a template tag and Turbo does the rest.\n\nReuse the server-side templates: Live page changes are generated using the same server-side templates that were used to create the first-load page.\n\nHTML over the wire: Since all we’re sending is HTML, you don’t need any client-side JavaScript (beyond Turbo, of course) to process the update. Yes, the HTML payload might be a tad larger than a comparable JSON, but with gzip, the difference is usually negligible, and you save all the client-side effort it takes to fetch JSON and turn it into HTML.Simpler control flow: It’s really clear to follow what happens when messages arrive on the WebSocket, SSE or in response to form submissions. There’s no routing, event bubbling, or other indirection required. It’s just the HTML to be changed, wrapped in a single tag that tells us how.\n\nNow, unlike RJS and SJR, it’s not possible to call custom JavaScript functions as part of a Turbo Streams action. But this is a feature, not a bug. Those techniques can easily end up producing a tangled mess when way too much JavaScript is sent along with the response. Turbo focuses squarely on just updating the DOM, and then assumes you’ll connect any additional behavior using Stimulus actions and lifecycle callbacks.", | ||
"icon_path": "/images/turbo-streams.png", | ||
"external_link": { | ||
"title": "Come Alive with Turbo Streams", | ||
"url": "https://turbo.hotwired.dev/handbook/streams" | ||
} | ||
} |
Oops, something went wrong.