Skip to content

Instantly share code, notes, and snippets.

@xthezealot
Last active September 12, 2025 13:42
Show Gist options
  • Select an option

  • Save xthezealot/ec5491ac35b189d2279a1a88f054cc7a to your computer and use it in GitHub Desktop.

Select an option

Save xthezealot/ec5491ac35b189d2279a1a88f054cc7a to your computer and use it in GitHub Desktop.
Alpine.js Single Page Application
<!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>
<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>
<h1>Page 2</h1>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment