{"id":24083284,"url":"https://github.com/mitranim/simple-pjax","last_synced_at":"2025-04-30T18:23:08.900Z","repository":{"id":35102572,"uuid":"39277534","full_name":"mitranim/simple-pjax","owner":"mitranim","description":"Zero-configuration PJAX for typical websites","archived":false,"fork":false,"pushed_at":"2019-09-07T19:20:37.000Z","size":1346,"stargazers_count":49,"open_issues_count":2,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-26T06:56:57.514Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://mitranim.com/simple-pjax/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mitranim.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-17T22:14:38.000Z","updated_at":"2024-10-26T23:56:27.000Z","dependencies_parsed_at":"2022-08-18T01:55:33.480Z","dependency_job_id":null,"html_url":"https://github.com/mitranim/simple-pjax","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fsimple-pjax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fsimple-pjax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fsimple-pjax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fsimple-pjax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitranim","download_url":"https://codeload.github.com/mitranim/simple-pjax/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251758683,"owners_count":21639087,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-09T23:56:17.304Z","updated_at":"2025-04-30T18:23:08.855Z","avatar_url":"https://github.com/mitranim.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com)\n\n## TOC\n\n* [Description](#description)\n* [Installation](#installation)\n* [Usage](#usage)\n* [Configuration](#configuration)\n* [Methods](#methods)\n* [Gotchas](#gotchas)\n\n## Description\n\nLean library that improves page loading times for classic multi-page websites.\nGives them some of the advantages enjoyed by SPA (single-page apps).\nConfiguration is optional.\n\nSee a simple demo at https://mitranim.com/simple-pjax/.\n\nRead an explanatory post at https://mitranim.com/posts/cheating-for-performance-pjax.\n\n`Pjax` is a combo of `pushState` and `Ajax`. There are\n[other](https://github.com/defunkt/jquery-pjax) pjax implementations floating\naround, but most of them are jQuery-based or overengineered. Hence `simple-pjax`.\n\nTo explain what pjax is about, first let's get a rough idea of how page\ntransitions work on most sites:\n* Load and parse the new HTML document. Create a new JavaScript runtime.\n* Redownload all stylesheets, scripts, fonts, images, etc. (Connections take time even if the resources are cached.)\n* Parse and execute the downloaded scripts.\n* Parse styles and apply them to the document.\n* Throw away the current document and JavaScript runtime, switch to the new document and runtime.\n* Download and execute asynchronous scripts, if any.\n\nHere's how page transitions work with simple-pjax:\n* Load and parse the new HTML document.\n* Replace the contents of the current document.\n* Let it execute the new scripts, if any.\n\nBenefits:\n* Don't redownload stylesheets, scripts, fonts, images.\n* Don't execute scripts that have already been executed.\n* Keep the JavaScript runtime and WebSocket connections intact.\n\nThe benefits are especially dramatic on mobile devies and slow connections.\n\nWorks on IE10+. Has no effect in browsers that don't support\n`history.pushState`.\n\n## Installation\n\nGrab through your favourite package manager:\n\n```sh\nnpm i --save-dev simple-pjax\njspm install npm:simple-pjax\n```\n\nImport in your code:\n\n```javascript\nimport pjax from 'simple-pjax'\n```\n\nOr include as a script tag:\n\n```html\n\u003cscript src=\"simple-pjax.js\" async\u003e\u003c/script\u003e\n```\n\n## Usage\n\nWorks automatically. When navigating between internal pages, the library\nprevents a full page reload. Instead, it fetches the new document by ajax and\nreplaces the contents of the current document.\n\nAfter replacing the document, it executes any _inline_ scripts found in it.\nIgnores scripts with an `src` under the assumption that all pages have the same\nset of scripts, and they have already been downloaded.\n\nAffects both `\u003ca\u003e` clicks and `popstate` history events, such as when the back\nbutton is clicked.\n\nVisibly indicates loading when it takes a while (by default after 250 ms). You\ncan customise the timeout and the functions called to add and remove the\nindicator.\n\n## Configuration\n\n`simple-pjax` works with zero configuration, but it also exports an object with\nconfigurable properties and useful methods. In the presense of a\nCommonJS-compliant module system, it does a proper export; otherwise the object\nis assigned to `window.simplePjax`.\n\nExample config (see defaults in [source](src/simple-pjax.ts)).\n\n```javascript\nimport pjax from 'simple-pjax'\n\n// Timeout before calling the loading indicator function. Set to 0 to disable.\npjax.indicateLoadAfter = 100\n\n// Called when loading takes a while. Use it to display a custom loading indicator.\npjax.onIndicateLoadStart = function() {\n  document.documentElement.style.opacity = 0.5\n}\n\n// Called when loading ends. Use it to hide a custom loading indicator.\npjax.onIndicateLoadEnd = function() {\n  document.documentElement.style.opacity = null\n}\n\n// If a selector string is provided, it's checked every time when scrolling\n// to an element (e.g. via data-scroll-to-id). If an element with the\n// {position: 'fixed', top: '0px'} computed style properties is found, the\n// scroll position will be offset by that element's height.\npjax.scrollOffsetSelector = '.navbar-fixed'\n\n// If a string is provided, it will be used as the default value (default\n// element `id`) for the `[data-scroll-to-id]` attribute.\npjax.defaultMainId = 'mainView'\n```\n\nYou can prevent page scroll by adding the `data-noscroll` attribute to a\nlink:\n\n```html\n\u003ca href=\"/other-page\" data-noscroll\u003eclicking me doesn't scroll the page!\u003c/a\u003e\n```\n\nIf you want an individual link without pjax behaviour, add the `data-no-pjax`\nattribute:\n\n```html\n\u003ca href=\"/other-page\" data-no-pjax\u003eI have native behaviour!\u003c/a\u003e\n```\n\nBy default, links to the same page are ignored. If you want to force a page\nrefresh, add the `data-force-reload` attribute. This reload doesn't affect\nscroll position:\n\n```html\n\u003ca href=\"/current-page\" data-force-reload\u003eI sneakily refresh the page when clicked!\u003c/a\u003e\n```\n\n## Methods\n\nsimple-pjax exports one simple method that sneakily refreshes the current page,\nas if you clicked a `\u003ca\u003e` leading to this page. The refresh is done through pjax\nand doesn't destroy the JS runtime and other assets. It also doesn't affect\nscroll position.\n\n```js\nimport pjax from 'simple-pjax'\n\npjax.reload()\n```\n\n## Gotchas\n\nYou need to watch out for code that modifies the DOM on page load. Most websites\nhave this in the form of analytics and UI widgets. When transitioning to a new\npage, that code must be re-executed to modify the new document body.\n\n`simple-pjax` mitigates this in two ways.\n\nFirst, it automatically executes any inline scripts found in the new document.\nIf you embed analytics and DOM bootstrap scripts inline, they should work\nout-of-the-box.\n\nSecond, it emits two `document`-level DOM events, before and after the\ntransition. Use them to perform any necessary DOM mutations or cleanup. Example:\n\n```javascript\ndocument.addEventListener('simple-pjax-after-transition', () =\u003e {\n  // perform DOM mutations\n})\n\ndocument.addEventListener('simple-pjax-before-transition', () =\u003e {\n  // perform cleanup\n})\n```\n\n## ToDo\n\nInvestigate if it's possible to get the final URL of an XHR after a server\nredirect without using `responseURL`, which is still not supported in Safari 8.0\nand IE 11.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitranim%2Fsimple-pjax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitranim%2Fsimple-pjax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitranim%2Fsimple-pjax/lists"}