Last active
September 12, 2025 13:42
-
-
Save xthezealot/ec5491ac35b189d2279a1a88f054cc7a to your computer and use it in GitHub Desktop.
Alpine.js Single Page Application
This file contains hidden or 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
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>Alpine SPA</title> | |
| <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> | |
| <script> | |
| document.addEventListener("alpine:init", () => { | |
| Alpine.data("app", () => ({ | |
| page: "", | |
| init() { | |
| // handle back/forward via hash changes | |
| window.addEventListener("hashchange", () => { | |
| const route = location.hash.slice(1) | |
| if (route) this.loadPage(route) | |
| }) | |
| this.loadPage(location.hash ? location.hash.slice(1) : "page1.html") | |
| }, | |
| async loadPage(name) { | |
| // keep url hash in sync for navigation/back-forward | |
| if (location.hash.slice(1) !== name) location.hash = name | |
| // fetch only the file path; ignore query for file lookup | |
| const file = name.split("?")[0] | |
| const data = await (await fetch(name)).text() | |
| const div = document.createElement("div") | |
| div.innerHTML = data | |
| // execute inline scripts in the loaded fragment | |
| div.querySelectorAll("script").forEach((script) => { | |
| eval(script.textContent) | |
| script.remove() | |
| }) | |
| this.page = div.innerHTML | |
| }, | |
| })) | |
| }) | |
| </script> | |
| </head> | |
| <body x-data="app" @load-page="loadPage($event.detail)"> | |
| <main x-html="page" style="display: contents"></main> | |
| <hr /> | |
| <button @click="loadPage('page1.html?id=1')">Load Page 1</button> | |
| <button @click="loadPage('page2.html')">Load Page 2</button> | |
| </body> | |
| </html> |
This file contains hidden or 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
| <script> | |
| Alpine.data("page1", () => ({ | |
| id: null, | |
| init() { | |
| const paramsStr = location.hash.includes("?") ? location.hash.split("?")[1] : "" | |
| const params = new URLSearchParams(paramsStr) | |
| this.id = params.get("id") | |
| console.log("Page 1 initialized") | |
| }, | |
| })) | |
| </script> | |
| <div x-data="page1"> | |
| <h1>Page of item <span x-text="id"></span></h1> | |
| <button @click="$dispatch('load-page', 'page2.html')">Go to Page 2 (using $dispatch)</button> | |
| </div> |
This file contains hidden or 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
| <h1>Page 2</h1> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment