First of all, if there’s a better way, I’m open to suggestions.
I am allowed to change frontend, but not backend (CMS code). Every subpage of the website has an image that is loaded at the top of the page, just bellow navigation bar (after header.php). I can choose the image in CMS and it’s path is stored in database.
So let’s say an image (1920×1080) is named “image.jpg”. I need to load a resized image (640×360), which I generically named “image.mob.jpg” (and stored in the same place on server as original “image.jpg”) when image is loaded on a mobile device (really when screen width is less or equal 640px – I chose the number, perhaps it would be better to use 480px or 360px).
What I currently do
HTML
<body>
...
<?php
...
while ($row = mysqli_fetch_array($result)) {
if (isset($_SESSION['screen_width']) && ($_SESSION['screen_width'] <= 640)) {
// change "path/to/image.jpg" to "path/to/image.mob.jpg"
$row['image'] = substr($row['image'], 0, -4).".mob".substr($row['image'], -4);
} ?>
<div class="image" style="background-image: url('<?=$row['image']?>)"> ... </div>
...
<?php
if (isset($_SESSION['screen_width']) AND isset($_SESSION['screen_height'])) {
// echo 'Screen width: ' . $_SESSION['screen_width'];
} else if (isset($_REQUEST['width'])) {
$_SESSION['screen_width'] = $_REQUEST['width'];
header('Location: ' . $_SERVER['PHP_SELF']);
} else {
echo '<script type="text/javascript">window.location.href = window.location.href+"?width="+screen.width;</script>';
}
// echo $_SESSION['screen_width'] = "<script>document.write(screen.width)</script>"; ?>
</body>
This is somewhat simplified but basically what happens is this. On first visit, there is no width stored in $_SESSION
so it loads the big “image.jpg”. But before it actually loads it, it already executes javascript and reloads the page with $_GET
variable width in the URL. All visits but the first already have width stored in session, so the URL is always SEO friendly again. Also image path is renamed and the site loads “image.mob.jpg” if screen width is 640px at most.
This works perfectly.
The problem is I need to have all site URLs SEO friendly at all times, so it’s not allowed to have it “https://seo-friendly.url?=width={screen.width}”, even if only just once.
As you can see in the last commented line I also tried with echo $_SESSION['screen_width'] = "<script>document.write(screen.width)</script>";
, but obviously it doesn’t work on first page load since all PHP is executed before any JavaScript.
How do I solve this with AJAX (I need the whole code, cause I’m to dumb to understand other’s internet answers sigh) or if there is any better alternative.
Thank you in advance.
2
Answers
While the answer of @avcajaraville is very useful in general, it is the comment of @Paflow that helped me find the solution. No JavaScript involved.
HTML
I first used
<style type="text/css" scoped>
, but then I readscoped
is deprecated and using just<style>
inside of<body>
is allowed.Not the fanciest way, but it works!
As @Paflow pointed out, to do this in PHP is an unnecessary hassle and not the recommended or suited way of doing it.
It is close to virtually impossible to get the viewport on an HTTP GET request. There are certain hacky ways of achieving this, but they need some sort of extra requests via JS.
Your best option is to use HTML.
srcset
will have you covered!I would suggest something like:
This will, by default load you
image.mob.jpg
image, which will be served then as a performant base image, and if your browser supports srcset and the viewport is bigger than640px
, you will get the/image.mob.jpg
image.Say you want more sizes, then all you have is to add them to srcset attribute and specify different sizes:
MDN responsive images