Reconstructing github page from url modified with pushState/popstate - javascript

I'm trying to build a small homepage hosted on github-pages, with a (1) title, (2) navbar and (3) a content window. I'm updating the content with ajax and use pushState/popstate for url updating and browser history. The problem is that if one refreshes the page at e.g. user.github.io/content1, the page is not found (because the html file doesn't actually exist).
I read that if one controls the server, this is usually solved by redirecting (or mod_rewrite-ing) every requested deep link to one resource and from there reconstructing the page with javascript according to the requested link. On gh-pages, this is not possible, so I thought about actually creating all the html files reflecting the url paths, but with each of them only containing the javascript code to re-generate the corresponding state (so that e.g. if I want to update my title or the links in the navbar, I don't have to manually edit all of the html files).
I have read about Jekyll, but I'm a beginner and I'd like to program everything from scratch to learn something.
Do you think this approach is a waste of time? Are there better ways to do this?
Thanks a lot, Stefan

Two cases :
Making a Single Page Applivation (SPA)
Your SPA is a javascript application that needs to send datas to/from a server that stores them, and to render the results on the client side.
In this case, your problem is not a Jekyll problem, it's a data one.
You can then have a serious look at react, angular and so on, ...
Making static web pages
Github pages is using Jekyll to generate static pages.
This way you can generate static pages with a title, a specific navbar and content with nothing more.
In terms of development and performance, it will be far more efficient.
Why it's better ?
Still assuming that you're not building an SPA.
Anytime you make a change in gh-pages (anything new like page, post, ...), your site is rebuild (post, page, include like navigation, an so on).
New page -> commit to gh-pages -> new build -> everything is OK !

Related

Forcing refresh of cached JS in SPA (reactJS) that changes between requests using react router

I have come to the conclusion that my SPA using reactJS coupled with react router (react-router-dom 5, a client side routing service) CAN ONLY get a newly deployed javascript file IF IT is through a refresh. There is no other way. Am I wrong?
Scenario:
User is on the homepage
A new JS bundle gets deployed. (I am using webpack and using the following format: app.[hash].js as per webpacks's caching documentation. This is then referenced by index.html e.g. <script src="app.dc1abe70ccbf1b703e01.js">)
User now clicks on another link (new route) BUT the old JS still shows (even though there is new code available)
Only when a user does a refresh of the page, does the new code show. (Http status 200 and then 304 on each subsequent refresh until JS changes again which will result in another 200 and so on)
Now, I have gone though several threads, but I am still not clear on how to implement a simple solution to get a freshly deployed JS file WITHOUT a refresh from the back end for an SPA (ReactJS) using react router that replaces a cached version of the JS file between requests.
My understanding
When you use react router, a route is loaded within the SPA when clicked (client side) without requesting any html or js from the back end because there is no need to. i.e. the loading is instant because it's meant to be an SPA. This makes sense because as I said, when the app is loaded the first time, app.[hash].js is downloaded and subsequently referenced.
I have seen many other threads offering various solutions like:
forcing the server to issue a new JS file: script.js?v=1 This however is a hack and you will end up with multiple versions of js files in your browser as per this. Besides, I am using routes (essentially, links managed through react router). I think script.js?v=1 is for individual links. I am also using webpacks format for my js references: app.[hash].js
Others have asked the same question regarding caching and SPA's but never received replies like here and here
Conclusion and goal
According to this comment: This is expected behaviour and until user will not refreshes his page, new changes will not be loaded – Zohaib Ijaz Apr 13 at 14:02 from this thread
MOSTLY everything I have researched does not speak specifically to ReactJS PLUS react-router-dom. They mention versioning js files with a ?ver=xyz but that is for individual links I believe, NOT a router with routes. Some others mention using app.[hash].js but then stop short to explaining what to do next.
EVERYTHING I have researched leads me to believe that in order to see new JS changes the next time a react router link is clicked, my ReactJS SPA with react-router can only see these new changes if it is refreshed. And if so, then there is NO SOLUTION but to hope the customer will refresh the page (because this IS the practical solution)?
p.s I am using express server

share component between pages without reloading it

Do any of you know how can I share a component between several html pages but load it only once?
I`m trying to share a unit canvas between several pages, but it takes too long to load, so every time I change the page it loads again, causing a very poor user experience. I tried to create the frame once and put it on session to be reused, but it seem to be not the fix for it.
I need to use the same component amongst all the pages without reloading it every time the user changes the browser address.
Thank you.
we had the same problem with adding the communicator to out online app (something like on FB). The best solution is to do a single page application and manage urls by html5 history API, but is only applicable when you start development. You could also try something with iframe e.g. put canvas in main document and the rest (changing part) in iframe, but you will have a problem with urls, so it isn't solution.
Becouse we had working app when we started work on communicator we ended up with everything store in session like you did.

How does angularjs not refresh on page change?

I've been learning about angularjs and have been very confused about how angular manages to change pages without refreshing and yet have a completely different view.
Are they actually changing the page URL or just hiding all the elements of on page and showing the other?
This video by CodeSchool explains it quite well.
AngularJS is just a tool that allows you to build single-page web applications with relative ease. What you are looking for is actually the definition of Single-Page Application:
Single-Page Applications (SPAs) are Web apps that load a single HTML page and dynamically update that page as the user interacts with the app. SPAs use AJAX and HTML5 to create fluid and responsive Web apps, without constant page reloads. However, this means much of the work happens on the client side, in JavaScript.
Also, from http://www.johnpapa.net/:
A SPA is fully (or close) loaded on the initial page load, it’s key
resources are preloaded, and progressively downloads features as
required.
And, more specific to your particular question:
When a user clicks on a menu item, the SPA sees that url and
translates it to a View that should be displayed. If the view has not
been seen before, the application may make an HTTP request to retrieve
the HTML template for the view. Then it will compose the view, fill in
the template, and display the view in the appropriate location within
the shell. If the view has already been viewed once, the browser may
have cached it and the router will be smart enough not to make the
request. This is one way a SPA can reduce round-tripping to and from a
server, and thus improve performance.
Keep in mind that this behavior is attained with the use of JavaScript, and does NOT require any specific library or framework (such as AngularJS), although you will probably want to learn how to use one to facilitate the process.
I also recommend you check these resources:
http://johnpapa.net/building-single-page-apps-with-knockout-jquery-and-web-api-ndash-the-story-begins/
http://www.johnpapa.net/pageinspa/
If your url's are mapped with the $routeProvider, you can reload a controller invoking $route.reload().

AngularJS + Parse Website Search Engine Optimization

I have developed a AngularJS Application together with a Parse.com backend (only data, no business logic). They communicate over REST.
Now my problem is, that I would like to get my page indexed by google. To reach that, I somehow have to serve all my content as static pages to make sure, Google can index it.
Now I found a nice service called getseojs.com, which does nothing else than serving all contents of my website as static content.
All i had to adjust on my side was to add a Rewrite-Condition and Rule into my .htaccess file which does nothing else than forwarding all calls containing a "_escaped_fragment_=" to the getSEOjs Service.
My only problem is, that my links arent working in the static version.
The reason is quite simple:
The URL of my AngularJS application is something like www.mydomain.com/app/
Now my links look like this:
Sample Content which is working fine in normal Browsers.
The problem is, that in the static content the domain is different. It is something like:
http://getseojs.com/v2/sdfxsaa2/://www.mydomain.com:80/app/?_escaped_fragment_=/sample/content
for the same Sample Content site. When I click on a link on the static site, I get redirected to something like:
http://getseojs.com/v2/sdfxsaa2/://www.mydomain.com:80/app/?_escaped_fragment_=/sample/content#!/othercontent
instead of
http://getseojs.com/v2/sdfxsaa2/://www.mydomain.com:80/app/?_escaped_fragment_=/othercontent
Is there any way I can avoid this? Is there no other way than working with absolute URLS? But also then I got a problem, because I need the /app/ part (cause this is were my website is placed in) and between the app part and the routes I need the hashbang (#!) oder in case of googlebot the part with "?_escaped_fragment_=".
I hope someone of you can help me. I have no idea how to solve this issue.
Thanks a lot.
Greets
Marc

Javascript file modifying an html file that it is not called from? Jquery Selectors

Is its possible to have a javascript file that is aware of two different HTML files? And how would I do this?
I would like to be able to have two pages. index.html and pictures.html. I have an index.js that changes the display properties of index.html (it puts data based on people into tables and makes it look nice). I would like this current index.js file also to be able to edit the pictures.html file and change information there. index.html would link to pictures.html to display pictures of a person (based on the persons name I have them saved smith1.jpg, smith2.jpg, reagan2.jpg, ect). Is there anyway that this javascript file could get DOM elements based on their id or class of the second file (pictures.html) even though it "lives in" index.html? When i say lives in it is called at the top of the index.html page.
thanks
A script can access elements on another page if it was loaded in some way of connection.
For example, if you make a popup using var popup = window.open(), the return value will contain a reference to the opened popup and this allows access to elements within the popup. E.g. popup.document.getElementById('something'). Pages loaded within frames, iframes and such have similar ways of access.
So yes, if your page loads the second page its script can work there as well. I suggest avoiding this beyond opening and closing popups from a script though; a script should stay inside the box of its page and if it needs to do larger operations on another page, that usually means that you need to change your code architecture a bit.
You'll need to explore server-side programming to accomplish your goal.
http://en.wikipedia.org/wiki/Server-side_scripting
...Or you could write a client-side application in which "pages" are separate views of one actual page or are generated from backing data structures. If you want persistance of what is created/edited, you'll still need server-side programming.
You can use the html5 (group of technologies) postmessage api as well.. This allows you to send messages to another page, and in that page you define an event handler that knows how to handle the message.
This also works across domains.
Here is a blog with an example I just randomly found via google:
http://robertnyman.com/2010/03/18/postmessage-in-html5-to-send-messages-between-windows-and-iframes/
Not possible on the client side if editing the actual HTML file is your goal. If getting pictures to show up depending on stuff a user does on another page is all you care about then there are lots of options.
You can pass small sets of data like stuff the user entered into tables via cookies for accessing the right sets of image files in a pre-established scheme. This would actually persist until a user cleared out cookies.
You could wrap both pages in same-domain iframe elements with the parent element containing just the JS. This would allow you to persist data between pages and react to iframe load events but like everything in client-side JS, it's all gone when you reload the page.
Newer browsers have working file access objects that aren't total security nightmares. These are new and non-standard enough that it would take some doing to make it work for multiple browsers. This could be used to save files containing info that the user would probably have to be prompted to upload when they return to the site.
If the data's not sensitive you could get creative and use another service to stash collections of data. Use a twitter API to tweet data to some publicly visible page of a twitter account (check the Terms of Service if you're doing anything more than an isolated class project here). Then do an Ajax get request on whatever URL it's publicly visible at and parse the HTML for your twitter data.
Other stuff I'd look into: dataURIs, html5 local storage.
Note: None of these are approaches I would seriously consider for a professional site where the data was expected to be persistent or in any way secure regardless of where a user accesses it from.

Categories

Resources