How to temporarily store a user’s data so they can retrieve it on another device

I have developed a small web game in HTML/JS (with Vue.js) where players can come every day to play a new game. I plan to add a statistics system soon so that players can track their progress. Their statistics will be stored in localStorage and updated every day after the end of a game.

So far, so good.

Now I’m looking to integrate a feature that allows players to transfer their stats from one device to another (PC to mobile and vice versa, since the statistics are specific to the browser used), and that’s where I don’t know how to proceed. I’ve seen that similar games such as Gamedle and Loldle offer this feature, where they generate a token that users can copy and paste onto their other device.

I had thought about setting up a database specifically for this purpose, or creating a file on my server where I would write the token (generated beforehand) + the local storage data, but I noticed that the two sites mentioned above have made sure that the token has a limited lifespan, so I wondered if they had done something else or used a third-party API. I don’t know…

Can you tell me what you think would be the simplest and most practical method to implement for temporarily storing a user’s game data on the server side so that they can transfer it to another device?

Thanks in advance!

What languages, frameworks and libraries should I use for my web application? [closed]

I’m working on a project, and I’d love to get advice from experienced web developers about the best technologies to use.

Here’s the idea:
The application will allow this fictional restaurant’s guests to scan a QR code at their table, which takes them to a web interface where they can build and submit their order.

There will be three main parts:

Guest interface: Guests choose and customize their meals, then submit the order.

Waiter interface: Waiters can see incoming orders in real time, sorted by table.

Admin interface: The restaurant admin can update menu items, prices, and availability.

I’d like to have real-time updates so waiters see new orders immediately and guests can track order progress.

I already know HTML, CSS (including Tailwind and Bootstrap), PHP (started learning Laravel), JavaScript (started learning Node.js), C#, and some Python. My goal is to choose a tech stack that’s realistic for my skill set.

Which languages, frameworks, or libraries would you recommend for building such a project? Should I stick with PHP/Laravel for the backend, or would Node.js be a better choice for real-time communication? For the frontend, would you suggest a framework like Vue or React, or something else?

Any advice would be greatly appreciated!

I want to know how to freeze the header row when scrolling down

<div class="table-responsive" style="max-height:540px; overflow-y:auto;">
    <table class="table table-bordered" style="table-layout: fixed; width: 100%;">
        <thead class="thead-light">
            <tr>
                <th class="sticky-top bg-white">Status</th>
            </tr>
        </thead>
        <tbody>
            <tr><td>test</td></tr>
        </tbody>
    </table>
</div>

I also tried using a table with display: block;:

<table class="table table-bordered" style="width: auto; max-height: 540px; display: block;">
</table>

With this approach, the header froze, but the columns got misaligned.
I want a table with a scrollable body and sticky headers, while keeping all columns correctly aligned.
How can I achieve this?

Datediff subtract time between two times (non working hours)

I am using datediff to work out how many hours and minutes it takes to go from one department (timestamped) to another department (timestamped).

If a department starts the task but doesn’t complete it that working day, but finishes the following day, the data is ‘incorrect’ as it has added non-working hours (overnight) to it.

This is being displayed through the DataTables plugin.

Please, can I get advice on creating a SQL Statement that ignores or subtracts the non-working hours?

Or maybe there is a better way around this?

Current PHP Code:

<table id="example" class="SizeTable" border="1" width="100%">
<thead>
<tr>
<th style="font-size: 1rem">PON</th>
<th style="font-size: 1rem">Total Doors</th> 
<th style="font-size: 1rem">Fold<br>Complete</th> 
<th style="font-size: 1rem">Folding Time<br>H:M</th> 
<th style="font-size: 1rem">Weld<br>Complete</th>
<th style="font-size: 1rem">Welding Time<br>H:M</th> 
<th style="font-size: 1rem">Painted<br>Complete</th>
<th style="font-size: 1rem">Painting Time<br>H:M</th> 
<th style="font-size: 1rem">Assembly<br>Complete</th>  
<th style="font-size: 1rem">Ordered<br>Date</th>
<th style="font-size: 1rem">Lead<br>Time</th>
<th style="font-size: 1rem">Due<br>Date</th> 
</tr>
</thead>
<tbody>
<?php
    include('connection.php');
    $select_query = mysqli_query($connection,"SELECT PON, dateOn, dueDate, foldedStart, weldedStart, paintedStart, assemblyStart, DATEDIFF(dueDate,dateOn) AS days, (
    requiredDoors +
    requiredDoors2 +
    requiredDoors3 +
    requiredDoors4 +
    requiredDoors5 +
    requiredDoors6 +
    requiredDoors7 +
    requiredDoors8 +
    requiredDoors9 +
    requiredDoors10 +
    requiredDoors11 +
    requiredDoors12 +
    requiredDoors13 +
    requiredDoors14 +
    requiredDoors15 +
    requiredDoors16 +
    requiredDoors17 +
    requiredDoors18 +
    requiredDoors19 +
    requiredDoors20 
    ) AS total FROM WIP2 WHERE status = '12'
    OR DATEPART(WEEKDAY,foldedStart) NOT IN (7, 1)
    AND assemblyStart NOT LIKE '%red%' 
    AND assemblyStart NOT LIKE '%InProgress%' 
    AND paintedStart NOT LIKE '%red%' 
    AND paintedStart NOT LIKE '%InProgress%' 
    AND weldedStart NOT LIKE '%red%' 
    AND weldedStart NOT LIKE '%InProgress%' 
    AND foldedStart NOT LIKE '%red%' 
    AND foldedStart NOT LIKE '%InProgress%' 
    ORDER BY dueDate desc");
    while($data = mysqli_fetch_array($select_query)){
?>
<?php
  $fold = date_create($data["foldedStart"]);
  $weld = date_create($data["weldedStart"]);
  $paint = date_create($data["paintedStart"]);
  $assembly = date_create($data["assemblyStart"]);  
  $interval1 = date_diff($fold, $weld);
  $interval2 = date_diff($weld, $paint);
  $interval3 = date_diff($paint, $assembly);
?>
<tr>
<td><?php echo $data['PON']; ?></td>
<td><?php echo $data['total']; ?></td>  
  
<td><?php echo $data['foldedStart']; ?></td>
<td><?php echo $interval1->format('%H:%I'); ?></td>
<td><?php echo $data['weldedStart']; ?></td>
<td><?php echo $interval2->format('%H:%I'); ?></td>
<td><?php echo $data['paintedStart']; ?></td>
<td><?php echo $interval3->format('%H:%I'); ?></td>
<td><?php echo $data['assemblyStart']; ?></td>
<td><?php echo $data['dateOn']; ?></td>
<td><?php echo $data['days']; ?></td>
<td><?php echo $data['dueDate']; ?></td>
</tr>   
<?php } ?>
</tbody>
</table>

Screenshot

MariaDB / PDO / PHP 1020 error (“Record has changed since last read in table”)

How do I correctly deal with 1020 errors within a transaction in MariaDB?

I recently encounter 1020 “Record has changed since last read in table” errors on code that run without this error for 20 years. It is hard to believe that the “record has changed since last read in table” because the failing SQL query is only for records used by one user (visitor):

DELETE FROM vbshoppingcart where visitor_id = :visitor_id AND businessunitID = :businessunitID

Anyway, when this error occurs I try to catch it and run the query again, because it actually should be a temporary failure:

$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
$this->dbh->beginTransaction();

// other queries within the same transaction will precede the query in question

$retry_attempts = 3;
$retry_wait_microseconds = 100000; // 100ms

while ($retry_attempts > 0) {
  $this->stmt = $this->dbh->prepare($this->query);
  $this->bindparams();
        
  try {

    $returnvalue = $this->stmt->execute();
    $this->clearBindvalues();

    return $returnvalue;
            
  } catch (PDOException $e) {
    $error_code = $e->getCode();
    $error_message = $e->getMessage();

    if ($error_code === 'HY000' && strpos($error_message, '1020') !== false) {
      // Retry in case of 1020
      error_log("Retry because of error 1020 – remaining: $retry_attempts.");

      usleep($retry_wait_microseconds);
      $retry_attempts--;
      continue;
    }

    // If no possibility that the query can be successfully executed clear the bind values in order to have the object ready for additional DB queries

    $this->clearBindvalues();
        
  }
            
  throw new Exception('PDO error occurred. Could not perform desired database interaction.');
        
}

// other queries within the same transaction will follow the query in question

try {

  // At the end the transaction will be committed:
  $result = $this->dbh->commit();

} catch (PDOException $e) {

  error_log("Commit failed: " . $e->getMessage());
  $this->dbh->rollBack();

  throw new Exception("Transaction commit failed: " . $e->getMessage());
}

I run this in a transaction (as shown in the code) with other queries before and after the query that sometimes causes trouble. If a 1020 error is thrown, always the first retry will already be executed successfully and the script goes on. At the end, the transaction will appear to be successfully committed (according to the logs), but in reality the entries will not be written to MariaDB.

How to prevent exposing real data in AJAX response (SSR vs CSR) and instead return opaque tokens?

I’m comparing two ways of rendering HTML structures with data from PHP + MySQL.

Option 1: SSR (Server-Side Rendering)

PHP builds the HTML and returns it directly:

PHP:


else if(isset($_POST["retrieveData"])){

  $sql = "SELECT * FROM sampleTable";

  $result = $conn->query($sql);

  $data = '';

  while($row = $result->fetch_assoc()){

    $data .= '<div class="Sample">';

    $data .= '<p class="ticket-id">'.$row["ticket"].'</p>';

    $data .= '<p class="email">'.$row["email"].'</p>';

    $data .= '</div>';

  }

  echo $data;

}

JS:

$.ajax({

  method: "POST",

  url: "PostData.php",

  data: { retrieveData: true },

  success: function(response){

    $('.container').append(response);

  }

});

Option 2: CSR (Client-Side Rendering)

PHP only returns JSON, and JS builds the HTML:

PHP:

else if(isset($_POST["retrieveData"])){

  $sql = "SELECT * FROM sampleTable";

  $result = $conn->query($sql);

  $rows = [];

  while($row = $result->fetch_assoc()){

    $rows[] = [

      "ticket" => $row["ticket"],

      "email"  => $row["email"]

    ];

  }

  echo json_encode($rows);

}

JS:

$.ajax({

  method: "POST",

  url: "PostData.php",

  data: { retrieveData: true },

  success: function(response){

    let a = JSON.parse(response);

    for(let i=0;i<a.length;i++){

      let b=a[i];

      let html=`

      <div class="Sample">

        <p class="ticket-id">${b.ticket}</p>

        <p class="email">${b.email}</p>

      </div>`;

      $('.container').append(html);

    }

  }

});

The problem

Both options expose the real data in the AJAX response. For example, if a user opens DevTools and adds console.log(response) inside my JS file:

Option 1 (SSR) response will log raw HTML with IDs and emails.

Option 2 (CSR) response will log JSON with the same IDs and emails.

So sensitive values (like ticket IDs or emails) are directly visible in the client.

What I want

Instead of returning the actual data directly in the AJAX response, I’d like to return only opaque/random alphanumeric tokens (e.g. 3f9aX2kP…).

Later, when the client needs to use those tokens, the server should be able to resolve them back to the real data.

My questions:

  1. Is it possible for a user to modify my JavaScript in Chrome DevTools and see raw AJAX responses? (I assume yes, but want confirmation.)

  2. What’s the standard way to return tokens instead of real data in AJAX responses, while still making the real data retrievable later?

Should I generate random strings and map them server-side (DB/session)?

Or use signed tokens (like HMAC/JWT) so the server can verify them without storing mappings?

How do I prevent replay or tampering?

Resolve PHP Notice Function _load_textdomain_just_in_time

I have an old abandoned plugin that I still use and so I cant have the developer to update it. I am receiving 1000s of PHP notices a day in my debug log with the _load_textdomain_just_in_time error.

This is the notice:

PHP Notice: Function _load_textdomain_just_in_time was called
incorrectly. Translation loading for the visitor-maps domain was
triggered too early. This is usually an indicator for some code in the
plugin or theme running too early. Translations should be loaded at
the init action or later. Please see Debugging in WordPress for more
information. (This message was added in version 6.7.0.)

In my attempts to try and correct the code – I have researched fixes where it shows the ‘wrong’ code and then the ‘correct code’ but the examples I have seen – none are worded the exact same as what I have, and so I am unsure and hesitant – for example see this link: Notice: Function _load_textdomain_just_in_time was called incorrectly

I believe I have found the code lines in the plugin that is causing the error in my abandoned plugin:

----
function visitor_maps_init() {

 if (function_exists('load_plugin_textdomain')) {
      load_plugin_textdomain('visitor-maps', false, 'visitor-maps/languages' );
 }
 ----

Could anyone advise how I could adjust the above code so that it resolves the php notice?

How to handle queued jobs failing silently when using Redis with Laravel 10 Horizon?

I’m working on a Laravel 10 project that uses Redis as the queue driver with Horizon. I’ve noticed that sometimes my queued jobs don’t execute, and nothing shows up in the failed_jobs table either.

  • Horizon dashboard shows the job was processed.

  • No exceptions are being logged.

  • The job logic isn’t running whatsoever (no db updates, no logs).

Things I tried:

  • Forcing queued jobs with php artisan queue:retry

  • Checking supervisor logs (no problems to speak of)

  • Check Redis running fine

How to change input value on Webflow Designer through google chrome console code?

I need to change field values on “custom properties” section of webflow designer using javascript code on google chrome console

fields to change

Also, after changing, it should be saved on editor like I entered that manually.

How can I achieve needed result?

Currently i`m trying to use

input.value = needed_value; 

That`s not helped to me

After that I tried to emulate firing events

const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
    nativeInputValueSetter.call(input, newValue);

input.dispatchEvent(new Event('input', { bubbles: true }));
input.dispatchEvent(new Event('change', { bubbles: true }));
input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true }));

That also not helped me.

What else methods should I try?

How do I access a dynamic variable returned by a function that is inside another function

I ma trying to first create the tic tac toe game on the console.
What I want
Before the playRound function is called, the value of the targeted cell should be zero otherwise the playround function should not be called.

function Gameboard() {
  const rows = 3;
  const columns = 3;
  const board = [];

  for (let i = 0; i < rows; i++){
    board[i] = []
    for (let j = 0; j < columns; j++) {
      board[i].push(Cell());
    }
  }

  console.log(" board display");  
  console.log(board);


  const dropToken = (column, row, player) => {
 
    const currentValueCell = () => board[row][column].getValue()
    
    console.log(currentValueCell());
    console.log(board[row][column].getValue());
    return board[row][column].addToken(player);

 
}


  const  printBoard = () => {
    const boardWithCellValues = board.map((row) => row.map((cell) => cell.getValue()))
    console.log(boardWithCellValues);
  };

  return {
    printBoard,
    dropToken,
    board,
    
  };
}

function Cell() {
  let value = 0;
  const addToken = (player) => {
      value = player
  };

  const getValue = () => value;

  return {
    getValue,
    addToken
  };
}


function GameContoller(
    playerOneName = "player One",
    playerTwoName = "player Two"
) {
    const board = Gameboard();

    const players = [
        {
            name: playerOneName,
            token: 1
        },
        {
            name: playerTwoName,
            token: 2
        }
    ];

    let activePlayer = players[0];

    const switchPlayerTurn = () => {
        activePlayer = activePlayer ===  players[0] ? players[1] : players[0];
    };

    const getActivePlayer = () => activePlayer;

    const printNewRound = () => {
        board.printBoard();
        console.log(`${getActivePlayer().name}'s turn.`);
    };


    const playRound = (column, row) => {
        console.log(
            `Dropping ${getActivePlayer().name}'s token into ${column} and  ${row}...`
        );
        board.dropToken(column,row, getActivePlayer().token);
        console.log(board.dropToken().currentValueCell);//What I have tried to access the value of the targeted cell

        switchPlayerTurn();
        printNewRound();

        

    };

    printNewRound();

    return{
        playRound,
        getActivePlayer
    };
}

const game = GameContoller();

THis is the current code of what I have tried. My expectation was If I use the currentValueCell function inside the dropToken function it is able to capture the value of the cell at the time then I can be able to use that variable inside the playground function

Uncaught Error in MInd AR js using Django for Ar based website

MindAR “RangeError: Extra N byte(s) found at buffer[1]” + “AR target element not found”

Problem
MindAR throws RangeError: Extra XXXX byte(s) found at buffer[1] when loading a .mind marker file. Additional logs show AR target element not found and a browser extension message-channel warning.

Environment

  • A‑Frame: 1.4.0
  • three.js: ^0.147.0
  • mindar-image-aframe
  • Marker path: /media/markers/baby121/baby121.mind

Observed Logs (trimmed)

Valid MIND format detected: 88919 byte payload
Received 88927 bytes, Content-Type: application/octet-stream
Uncaught (in promise) RangeError: Extra 4167 of 4168 byte(s) found at buffer[1]
AR target element not found

Root Cause

MindAR validates the marker file length against its header. The served file contains extra bytes compared to the header (e.g., expected 88919, received 88927). This typically happens when:

  • An edge/proxy (Cloudflare/Tunnel, etc.) compresses or rewrites binary files (gzip/brotli) or appends bytes.
  • The file was uploaded in text mode (CRLF/BOM) or otherwise corrupted.
  • The URL returns HTML or a partial/concatenated response instead of the raw binary.

AR target element not found is a separate DOM timing/selector issue: tracking starts before the <a-entity mindar-image-target> exists.

The message-channel warning usually comes from a browser extension and is unrelated.


Fixes

A) Serve .mind files as raw, uncompressed binary

Headers:

  • Content-Type: application/octet-stream
  • No Content-Encoding (disable gzip/brotli)
  • Avoid any response transformations.

Nginx

location /media/markers/ {
    types { application/octet-stream mind; }
    default_type application/octet-stream;
    gzip off;  # ensure no compression
    add_header Cache-Control "public, max-age=31536000, immutable";
}

Apache

AddType application/octet-stream .mind
SetEnvIfNoCase Request_URI ".mind$" no-gzip=1
Header set Cache-Control "public, max-age=31536000, immutable"

Cloudflare/Proxy
Add a rule to bypass cache/transforms for *.mind or enforce Content-Encoding: identity at origin. Disable minify/compression for that path.

B) Verify served bytes match the source

Node quick check

const fs = require('fs');
const https = require('https');
const crypto = require('crypto');

// local file
const a = fs.readFileSync('./baby121.mind');
console.log('local', a.length, crypto.createHash('sha256').update(a).digest('hex'));

// remote file
https.get('https://your-domain/media/markers/baby121/baby121.mind', res => {
  const chunks = [];
  res.on('data', d => chunks.push(d));
  res.on('end', () => {
    const b = Buffer.concat(chunks);
    console.log('remote', b.length, crypto.createHash('sha256').update(b).digest('hex'));
  });
});

If lengths/hashes differ, the server/proxy is modifying the file. Fix config and/or re‑upload in binary mode.

C) If manually fetching, read as arrayBuffer()

const res = await fetch('/media/markers/baby121/baby121.mind', { cache: 'no-cache' });
const buf = await res.arrayBuffer();         // ✅ not res.text()
const blob = new Blob([buf], { type: 'application/octet-stream' });
const url  = URL.createObjectURL(blob);
// Use `url` in MindAR config

D) Ensure the AR target exists before tracking

HTML skeleton

<a-scene mindar-image="imageTargetSrc: /media/markers/baby121/baby121.mind;"
         vr-mode-ui="enabled: false"
         device-orientation-permission-ui="enabled: true"
         embedded>
  <a-camera position="0 0 0" look-controls="enabled: false"></a-camera>
  <a-entity id="ar-target" mindar-image-target="targetIndex: 0">
    <a-entity gltf-model="#model" position="0 0 0" scale="0.2 0.2 0.2"></a-entity>
  </a-entity>
</a-scene>

JS timing guard

const sceneEl = document.querySelector('a-scene');
sceneEl.addEventListener('loaded', () => {
  const target = document.querySelector('#ar-target');
  if (!target) {
    console.warn('AR target element not found');
    // Optionally create/append the target here
  }
});

E) Re‑export marker if corrupted

If the on‑disk .mind already has the wrong size, regenerate it with MindAR CLI/Editor and upload again (binary mode). Avoid editing it in text editors.


What I tried
I set up an A-Frame (v1.4.0) + MindAR scene and served my marker file (baby121.mind) from /media/markers/baby121/. I also confirmed that the file was being fetched correctly by the browser and that it returned with Content-Type: application/octet-stream.

What I expected
I expected MindAR to load the .mind marker normally, initialize tracking, and then detect the target so I could attach my 3D model to it.

What actually happened
Instead, the console shows that the .mind file is detected but with mismatched byte sizes (e.g., “88927 bytes received” vs. “88919 payload”). This leads to RangeError: Extra XXXX byte(s) found at buffer[1]. At the same time, I also get AR target element not found. As a result, the AR experience never starts properly.

How to concate two objects, and if any keys are the same between the two objects, sum the elements [duplicate]

// Complete the function mergeObjects(obj1, obj2) that returns a new object containing all properties of obj1 and obj2
// If a property exists in both objects, add them together (ints) or concatenate them (arrays/strings)
function mergeObjects(obj1, obj2) {
    let obj = new Object();

    let key1 = Object.keys(obj1);
    let key2 = Object.keys(obj2);
}

This is all i have so far. I’m not too sure of what to do… If anyone can give me some perspective or a hint that would be great

Pick Group and Rank question in qualtrics. Groups to be editable during preview

I was wondering if it is possible for be able to have the user be able to rename the groups for the question type pick group and rank when they are doing the survey (not in survey editor)

Possibly using javascript or anything else, would greatly appreiciate any help. Im not very good with javascript, and tried to use gpt which came up with this code



Qualtrics.SurveyEngine.addOnReady(function() {

  // Select all group headers (Qualtrics usually uses these classes)

  let groupHeaders = document.querySelectorAll(".ChoiceGroupHeader, .RankGroupHeader, .Editable.Answer");



  groupHeaders.forEach(header => {

    // Create an input field to replace the header text

    let input = document.createElement("input");

    input.type = "text";

    input.value = header.innerText.trim();

    input.style.border = "1px solid #ccc";

    input.style.borderRadius = "6px";

    input.style.padding = "2px 6px";

    input.style.fontSize = "14px";

    input.style.width = (header.offsetWidth || 120) + "px";



    // Replace the header content with the input

    header.innerHTML = "";

    header.appendChild(input);



    // Update the header text dynamically as the user edits

    input.addEventListener("input", function() {

      header.setAttribute("data-renamed", this.value);

    });

  });

});

But this did not work.

Thabk you all

How to use ACF OpenStreetMap Field plugin in WordPress with zoom setting?

I’m trying to figure out how to use Leaflet.js that’s inside the ACF Openstreetmap Field Plugin. I found a code that was helpful and I was able to modify to display the map on my wordpress website.

The way it works is that it collect the map/markers from the single campuses and display them all together in the main campuses map. However, the problem is that while it does work in the single campus page, it’s not showing the correct zoom setting on the single campus page.

Here are my steps:

  1. Install ACF OpenStreetMap Field Plugin

  2. When creating the Map Location Field Group in ACF, make sure to click on “Raw Data” under Return Format

  3. In functions.php, add this

wp_enqueue_style('leaflet-map-css', '//unpkg.com/[email protected]/dist/leaflet.css');
wp_enqueue_script('leaflet-map-js', '//unpkg.com/[email protected]/dist/leaflet.js', NULL, '1.9.4', false); 
  1. In index.js, add this
import LeafletMap from "./modules/Leaflet";
const leafletMap = new LeafletMap();
  1. In archive-campus.php, add this (This is where it collects all markers from single campus posts in main campuses page),
<div class="acf-map">
    <?php
    while(have_posts()) {
      the_post();
      $map_location = get_field('map_location');
    ?>
        <div class="marker"
            data-lng="<?php echo $map_location['markers']['0']['lng']; ?>"
            data-lat="<?php echo $map_location['markers']['0']['lat']; ?>"
        >
        <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
            <?php echo $map_location['address'] ?>
        </div>
    <?php } ?>
 
    </div>
  1. Add Leaflet.js file in js->modules folder (There’s no need to add Mapbox Token. I didn’t create an account or add any credit card info.)
class LMap {
  constructor() {
    document.querySelectorAll(".acf-map").forEach((el) => {
      this.new_map(el);
    });
  }
 
  new_map($el) {
    var $markers = $el.querySelectorAll(".marker");
 
    var map = L.map($el).setView([0, 0], 13);
 
    L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
      maxZoom: 19,
      attribution:
        '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
    }).addTo(map);
 
    map.markers = [];
    var that = this;
 
    // add markers
    $markers.forEach(function (x) {
      that.add_marker(x, map);
    });
 
    // center map
    this.center_map(map);
  } // end new_map
 
  add_marker($marker, map) {
    var marker = L.marker([
      $marker.getAttribute("data-lat"),
      $marker.getAttribute("data-lng"),
    ]).addTo(map);
 
    map.markers.push(marker);
 
    // if marker contains HTML, add it to an infoWindow
    if ($marker.innerHTML) {
      // create info window
      marker.bindPopup($marker.innerHTML);
    }
  } // end add_marker
 
  center_map(map) {
    var bounds = new L.LatLngBounds();
 
    // loop through all markers and create bounds
    map.markers.forEach(function (marker) {
      var latlng = new L.LatLng(marker._latlng.lat, marker._latlng.lng);
 
      bounds.extend(latlng);
    });
 
    map.fitBounds(bounds);
  } // end center_map
}
 
export default LMap;
  1. In single-campus.php, add this:
<?php
      $map_location = get_field('map_location');
      ?>
      
      <div class="acf-map">
        <div class="marker" data-lat="<?php echo $map_location['markers']['0']['lat'] ?>" data-lng="<?php echo $map_location['markers']['0']['lng']; ?>">
            <h3><?php the_title(); ?></h3>
            <?php echo $map_location['address']; ?>
        </div>
    </div>

So I tried to add the zoom setting to the code but it didn’t work in the single campus page as it was supposed to.

Here’s my attempt:

  1. single-campus.php
<?php
      $map_location = get_field('map_location');

      if ($map_location) {
        // print_r($map_location);
        $zoom_level = isset($map_location['zoom']) ? esc_attr($map_location['zoom']) : 14;
      }
      ?>
      
      <div class="acf-map" data-zoom="<?php echo $zoom_level; ?>">
        <div class="marker" data-lat="<?php echo $map_location['markers']['0']['lat'] ?>" data-lng="<?php echo $map_location['markers']['0']['lng']; ?>">
            <h3><?php the_title(); ?></h3>
            <?php echo $map_location['address']; ?>
        </div>
    </div>
  1. and I edited the new_map section in the Leaflet.js:
new_map($el) {
    var $markers = $el.querySelectorAll(".marker");

    var zoom_level = parseInt($el.getAttribute("data-zoom")) || 13;

    var map = L.map($el).setView([0, 0], zoom_level);

    L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
      maxZoom: 19,
      attribution:
        '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
    }).addTo(map);

Can you let me know what went wrong, please?

Express routes not being hit; router testing middleware never logs requests [closed]

I’m building a Node.js + Express backend with MongoDB and JWT authentication. I have a router userRoutes.js that handles /api/users endpoints, but none of the routes seem to be hit — even a simple console.log in the router middleware never prints.

My setup:

  • server.js
import express from "express";
import cookieParser from "cookie-parser";
import userRoutes from "./routes/userRoutes.js";

const app = express();
app.use(express.json());
app.use(cookieParser());

app.use("/api/users", userRoutes);
app.get("/", (req, res) => res.send("Server is ready"));
app.listen(5000, () => console.log("Server running"));
  • userRoutes.js
import express from "express";
import { registerUser, authUser } from "../controllers/userController.js";

const router = express.Router();

// Debug middleware
router.use((req, res, next) => {
  console.log("Request hit userRoutes:", req.method, req.originalUrl);
  next();
});

router.post("/", registerUser);
router.post("/auth", authUser);

export default router;

Issue:

  • When I make requests to /api/users/ or /api/users/auth, nothing logs in the console.
  • The root route / works fine.

Link to github repo

.env variables setup

MONGO_URI=
JWT_SECRET=
NODE_ENV=development

What I’ve tried:

  • Checked that the paths to the router and controller files are correct.
  • Verified that the server is running and listening on the right port.
  • Ensured express.json() and cookieParser() are used before the router.

Why aren’t requests reaching the userRoutes router? What might be causing the router middleware to never log requests?