Can’t change rooms using Socket.io

I’m attempting to integrate a way to change rooms using a function I already have that edits my html.

Client.js

function changeRoom() {
    let previousChat = currentChat;
    currentChat = newChat;

    // Emit the 'changeChat' event to the server
    socket.emit('changeChat');

Server.js

socket.on("changeChat", (previousChat, currentChat) => {
    socket.leave(previousChat);
    socket.room = currentChat;
    socket.join(currentChat);
  });

Is there a way to force an Android PWA to go back to its “start_url” from Javascript?

My app dynamically generates manifest.json for each user, so that there can be multiple homescreen shortcuts, each pointing to the user’s unique start_url. However, in case of a server error (and other cases), I’d like to have a link that lets the user go back to the initial page for that PWA. And because of the way that the app is designed, I can’t use any information provided by the server (session, cookies, generated html, manifest, etc.) — this has to be done purely in Javascript inside the PWA itself.

It’s easy enough to do in iOS, since PWAs are isolated, and have their own sandboxed localstorage. That way, I can save the initial URL into localstorage, and then retrieve it when needed.

But on Android, PWAs share their space with each other and the browser, so I can’t find any unique way that I can identify each of the PWAs

React-Router 6.23.0 – How to hide child path in the url after navigating to it

I have the following code for my routes in using react-router 6.23.0

const router = createBrowserRouter([
    {
        path: '/fruits',
        element: <Root />,
        errorElement: <ErrorPage />,
        loader: fruitloader,
        children: [
            {
                loader: bananaLoader,
                index: true,
                path: 'banana-services?',
                element: <BananaServices />
            },
            {
                loader: appleLoader,
                path: 'apple-services',
                element: <AppleServices />
            },
            {
                Loader: 'orangeLoader',
                path: 'orange-services'
                element: <OrangeServices />
            }
        ]
    }
]);
<AppContainerInnerContainer>
    <GlobalStyles />
    <Sidebar>
        <NavLink to="fruits/banana">Banana</NavLink>
        <NavLink to="fruits/apple">Apple</NavLink>
        <NavLink to="fruits/orange">Orange</NavLink>
    </Sidebar>
    <Detail>
        <Outlet />
    </Detail>
</AppContainerInnerContainer>

My requirement is that in the url path I don’t want the child paths to show after navigating to the “page”.

For example, when a user clicks on “Banana”, instead of what react-router gives me, http://www.example.com/fruits/banana.

I want http://www.example.com/fruits but still be able view the banana page. Sidebar should still be intact on the left side. This is similar experience with apple and orange as well. I only want /fruits to show despite the child they’re click on.

Any help would be appreciated here!

Node JS Express – Download window doesn’t appear until all file is sent in header response

I’m working with Express to create an api that allow to download a PDF file.
Download is working fine, but I don’t see the download window where I choose the folder I want to download, until all “download” is done in network connection.

enter image description here

This pdf is 22Mb.

Here’s part of my code:

const filePath = path.join(__dirname, serverPath.replace(/[/\]/g, path.sep))
    const fileStream = fs.createReadStream(filePath)

     fileStream
      .on('error', (error) => {
        next(error) // --> Send error to middleWare
      })
      .on('end', () => {
        logger.info(`${order} - File:${pathDB.fileName} from ${filePath} correctly Downloaded`)
      })

    // send file in https response, "blob" type
    res.setHeader('Content-Disposition', 'attachment; filename=' + pathDB.fileName)
    res.setHeader('Content-Type', 'application/octet-stream')
    fileStream.pipe(res)

I’ve tried adding Content-Length but doesn’t work.

const stat = fs.statSync(filePath);
const fileSize = stat.size;

res.setHeader('Content-Length', fileSize); // Set the Content-Length header

How should I manage it to allow user to select download folder before all pdf is downloaded?

For example, I’ve seen in AMD drivers website, when you click to download response sent a 200b object, popup the download window, and when you accept, the whole file is downloaded.
https://www.amd.com/en/support/download/drivers.html

Thanks and best regards

Absence of .env files on ec2 is failing the nestjs server to run on EC2 instance

I’m creating a NestJs Application and I’ve 2 env files, named

.local.env & .development.env

In local setting the variable from npm run start:dev and the start:dev looks like this "start:dev": "NODE_ENV=dev nest start --watch",

Now while importing the file i’m using the below snippet to load the specific file in local,

import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo";
import { TypeOrmModule } from "@nestjs/typeorm";
import { GraphQLModule } from "@nestjs/graphql";
import { CONSTANTS } from "../../../CONSTANTS";
import { ConfigModule } from "@nestjs/config";
import { databaseProviders } from "src/typeorm.config";
import { moduleIndex } from "./modules.index";
import { User } from "../graphQL/Users/users.entity";

let region: string = CONSTANTS.DEVELOPMENT_REGION;
if (process.env.NODE_ENV.toLowerCase() === CONSTANTS.DEVELOPMENT_REGION) {
    region = "development"
} else if (process.env.NODE_ENV.toLowerCase() === CONSTANTS.DEVELOPMENT_LOCAL_REGION) {
    region = "local"
} else if (process.env.NODE_ENV.toLowerCase() === CONSTANTS.DEVELOPMENT_STAGE_REGION) {
    region = "stage"
} else if (process.env.NODE_ENV.toLowerCase() === CONSTANTS.DEVELOPMENT_PROD_REGION) {
    region = "prod"
}
console.log("Region: ", region);
const importsArray = [
    GraphQLModule.forRoot<ApolloDriverConfig>({
        driver: ApolloDriver,
        autoSchemaFile: CONSTANTS.SCHEMA_FILE_PATH
    }),
    ConfigModule.forRoot({
        envFilePath: `.${region}.env`,
        isGlobal: true,
    }),
    TypeOrmModule.forRootAsync(databaseProviders),
    TypeOrmModule.forFeature([User])
]

const expArray = [...importsArray, ...moduleIndex];

export default expArray;

This configuration works prettymuch well in local, but when I build the project in Amazon Linux and run it using pm2 it’s not reading the NODE_ENV variable, neither the file itself.

I’m using ConfigService for reading env variables. like below,

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class AppConfig {
  static service: ConfigService;

  constructor(service: ConfigService) {
    AppConfig.service = service;
  }

  static get(key: string): any {
    return AppConfig.service.get(key);
  }
}

Use,

import { AppConfig } from '../app.config';

and using it like AppConfig.get('JWT_SECRET').

Can anyone please suggest me how can I handle .env issue on ec2.

Thanks in advance.

How to Hide bundle.js or source code Files of React webistes from Users?

I have a React-based website with a Django backend, deployed using Kubernetes and nginx. To manage secrets, I’ve utilized a .env file, storing sensitive information as process.env.var_name. However, after deployment, inspecting the website reveals the entire source code, including the secrets with their actual values, instead of process.env.var_name.

I’ve attempted solutions such as setting “GENERATE_SOURCEMAP=false” in .env and the build script of package.json, which successfully hide the source files of the website but not the bundle.js files under sourceTab/static/js.

I’m seeking advice on how to effectively secure my secrets and conceal the source code from clients.

Requirements:

Ensure that sensitive information stored in the .env file is not exposed in the source code visible to clients.
Conceal the source code files, including bundle.js, from being accessible through inspection or other means.
Minimize any performance impact or disruption to the existing deployment setup.

Browser router build not taking index.html as home page on npm run build in react-router-dom

I’m encountering an issue with React Router DOM when running npm run build. The problem arises when trying to set the homepage as index.html within the build folder. Despite trying various solutions like adjusting the package.json configurations and using BrowserRouter, the issue persists.

import React, { useEffect } from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import { HomePage } from "./Pages/Home/Home.js";
import ApplicationPage from "./Pages/ApplicationFresh/ApplicationPage.js";
import CutoffPage from "./Pages/CutoffCalc/Cutoff.js";
import ContactPage from "./Pages/ContactUs/ContactPage.js";
import FaqsPage from "./Pages/Faqs/FaqSection.js";
import PremiumBooks from "./Pages/Books/PremiumBooks.js";
import FreeBooks from "./Pages/Books/FreeBooks.js";
import Tawktochat from "./components/TawkChat/Tawkto.js";
import NotFound from "./Pages/Error/Notfound.js";
import WhatsAppChatBubble from "./components/Whatsapp/ChatComponent.js";
import { Box } from "@mui/material";

function App() {
  // DISABLE RIGHT CLICK
  useEffect(() => {
    const disableRightClick = (event) => {
      if (event.button === 2) {
        event.preventDefault();
      }
    };

    window.addEventListener("contextmenu", disableRightClick);

    return () => {
      window.removeEventListener("contextmenu", disableRightClick);
    };
  }, []);

  return (
    <Router basename={process.env.PUBLIC_URL}>
      <Routes>
        <Route exact path="/" element={<HomePage />} />
        <Route
          path="/NATA_Application_Form_2025"
          element={<ApplicationPage />}
        />
        <Route path="/nata-cutoff-calculator" element={<CutoffPage />} />
        <Route
          path="/NATA_Coaching_center_near_me_address"
          element={<ContactPage />}
        />
        <Route path="/faqs" element={<FaqsPage />} />
        <Route path="/Premium_Books" element={<PremiumBooks />} />
        <Route path="/NATA_Free_Books" element={<FreeBooks />} />
        {/* 404 */}
        <Route path="*" element={<NotFound />} />
      </Routes>
      <Box sx={{ display: "flex", justifyContent: "space-between" }}>
        <WhatsAppChatBubble />
        <Tawktochat />
      </Box>
    </Router>
  );
}

export default App;

index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { ThemeProvider, createTheme } from "@mui/material";

const theme = createTheme();

ReactDOM.render(
  <React.StrictMode>
    <ThemeProvider theme={theme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

reportWebVitals();


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!-- Google fonts -->
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="" />
    <link
      href="https://fonts.googleapis.com/css2?family=Handlee&amp;family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&amp;display=swap"
      rel="stylesheet"
    />

    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>neramClasses - Online NATA coaching classroom</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

The live site can be accessed here neramClasses.com.
Youtube API was working fine bbut now it is also not working.

I initially used BrowserRouter, which caused problems, so I switched to HashRouter for deployment. However, I prefer to use BrowserRouter for cleaner URLs and to resolve image location issues.

Any insights or solutions on how to properly configure React Router DOM to correctly route to index.html as the homepage during the build would be greatly appreciated. Thank you!

Creating a Gradient Background in a JavaScript-Generated Image File

I have written the following code to create a JPG image file that prints the gradient background of the HTML body as the image background:

const downloadButton = document.getElementById('downloadButton');

    downloadButton.addEventListener('click', function() {
      // Create a canvas element and set its dimensions
      const canvas = document.createElement('canvas');
      canvas.width = 500;
      canvas.height = 300;

      // Get the canvas context
      const ctx = canvas.getContext('2d');

      // Fill the canvas with the background Image
      const bodyStyle = document.body.style;
      const backgroundImage = bodyStyle.backgroundImage || 'white'; // Default to white if not set
      ctx.fillStyle = backgroundImage;
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      // Add text indicating background Image
      ctx.font = '20px Arial';
      ctx.fillStyle = 'black';
      const rgbColor = getRGBColor(backgroundImage); // Convert to RGB format
      ctx.fillText(`background Image : ${rgbColor}`, 200, 250); // Adjust position as needed

      // Convert the canvas to a data URL (PNG format)
      const dataURL = canvas.toDataURL('image/jpg');

      // Convert the data URL to a Blob object
      const blob = new Blob([dataURL.split(',')[1]], { type: 'image/jpg' });

      // Create a temporary URL for the Blob object
      const fileURL = URL.createObjectURL(blob);

      // Trigger the download of the JPG file
      const link = document.createElement('a');
      link.href = fileURL;
      link.download = 'image.jpg';
      link.click();

      // Revoke the temporary URL when done (optional)
      URL.revokeObjectURL(fileURL);
    });

    // Function to convert hex color to RGB format
    function getRGBColor(hexColor) {
      if (hexColor.length === 3) {
        hexColor = hexColor.repeat(2); // Duplicate for full RGB
      }
      const r = parseInt(hexColor.slice(0, 2), 16);
      const g = parseInt(hexColor.slice(2, 4), 16);
      const b = parseInt(hexColor.slice(4, 6), 16);
      return `rgb(${r}, ${g}, ${b})`;
    }

It creates a file named image.jpg, but it doesn’t open with any tool !?

My goal is simply to create a .jpg file that can render the background of the HTML body, which is:

body {
   background-image : linear-gradient(0deg ,rgb(0,0,153), rgb(107,0,0));
}

PayPal Smart/Hosted Button: callback on Approve/Capture

I am switching out a script block which used to use the subscription feature of PayPal. The code was basically this:

<script src="https://www.paypal.com/sdk/js?client-id=[id]=true&intent=subscription" data-sdk-integration-source="button-factory"></script>
<div id="paypal-button-container-P-[id]"></div>
<script>
    paypal.Buttons({
        style: {
             shape: 'rect',
             color: 'gold',
             layout: 'vertical',
             label: 'subscribe'
            },
        createSubscription: function(data, actions) {
            return actions.subscription.create({
            /* Creates the subscription */
            plan_id: 'P-[id]'
            });
        },
        onApprove: function(data, actions) {
            var subId = document.getElementById('subId');
            subId.setAttribute('value',  data.subscriptionID);
            var form = document.getElementById('membershipForm');
            form.submit();
        }
}).render('#paypal-button-container-P-[id]'); // Renders the PayPal button
</script>

After the payment goes through, I run the onApprove callback function to submit a form on the page with some site-specific information, and sends emails through the website.

The payment model has changed, and now we want to use single payments, not subscriptions.

I have tried using the “No-Code Checkout” AKA “HostedButton” AKA “Smart Buttons”. It generates this:

<script src="https://www.paypal.com/sdk/js?client-id=[id]&components=hosted-buttons&disable-funding=venmo&currency=CAD"></script>
<div id="paypal-container-[id]"></div>
<script>
paypal.HostedButtons({
    hostedButtonId: "[id]"
}).render("#paypal-container-[id]")
</script>

There’s no callback function in here. When someone finishes paying, they stay on the page and there is no feedback from the website or indication the transaction was made other than the pop-up closes.

I tried adding onApprove like before, but still nothing happens. Even simplifying the callback function to a console.log or alert does nothing. It doesn’t seem to ever get called.

paypal.HostedButtons({
    hostedButtonId: "[id]",
    onApprove: function(data, actions) {
    var subId = document.getElementById('subId');
        subId.setAttribute('value',  data.subscriptionID);
        var form = document.getElementById('membershipForm');
        form.submit();
        }
}).render("#paypal-container-[id]")

I’ve scoured PayPal’s documentation but I can’t find anything on this.
If it makes a difference, this is a button made in sandbox, being purchased with a sandbox test account, running everything on localhost.

Also note: there are no errors at any point in this process, and my sandbox account is getting the money.

alternative to exporting instantiated class in JavaScript?

according to this Is it bad practice to export instantiated class in JavaScript?, it is not recommended to export instantiated class.

If so, I want to ask is my following implementations count as an alternative.

my class:

export default class RouterConfig{
    constructor(header = '', parameters = []){
        this.path = parameters.reduce((accumulator, current) => `${accumulator}/:${current}`, header)
    }

    path: string;

    generateURL(data = {}){
        return this.parameters.reduce((accumulator, current) => `${accumulator}/${data[current]}`, `/${this.header}`)
    }
}

so intead of exporting like so:

const route1 = new RouterConfig('abc', ['param_C', 'param_O', ])
export default route1 

does that mean i need to export it like so:


const route2 = new RouterConfig('def', ['param_G'])

export const header       = route2.header
export const parameters   = route2.parameters
export const path         = route2.path
export const generateURL  = route2.generateURL.bind(route2)

I am trying to send a GET request but it always prints index.html file instead of the actual mongo db data in react.js

client-
Also I am getting an jwt error -jwt must be provided.

import { useEffect, useState } from "react";

const useGetConversation = () => {
    const [loading, setLoading] = useState(false);
    const [conversation, setConversation] = useState([]);

    useEffect(() => {
        const getConversation = async () => {
            setLoading(true);
            try {
        const jwtToken = document.cookie.split(';').find(c => c.startsWith('jwt='));
                const res = await fetch("/api/users", { 
          headers: {
            'Authorization': `Bearer ${jwtToken}`,
            'Content-Type':'application/json' 
          },
        });
                const data=await res.json()

        console.log(data)
                if (data.error) {
                    throw new Error(data.error);
                }
                setConversation(data);
            } catch (error) {
                console.error(error.message);
            } finally {
                setLoading(false);
            }
        };

        getConversation();
    }, []);

    return { loading, conversation };
};
export default useGetConversation;

backend-
If i replace the getuser function by another simple function ,it works fine.
The problem only happens when trying to work with this function.

import { User } from "../model/userModel.js"

const getUser=async(req,res)=>{
try {
    const loggedinUsers=req.user._id
    console.log(loggedinUsers)
    const filtereduser= await User.find({_id:{$ne:loggedinUsers}}).select("-password")
    if (!filtereduser) {
        return res.status(404).json({ message: 'User not found' });
        
    }
    res.status(200).json(filtereduser);
    // console.log(filtereduser)
} catch (error) {
    console.log('error while getting user',error.message)
    res.status(500).json({error:error.message})
}
}
export default getUser

router.js-

import express from 'express'
import getUser from '../controllers/userController.js'
import { protectRoute } from '../middleware/protectRoute.js'
const router=express.Router()
router.get("/",protectRoute,getUser) 
export default router

server.js-

import express from 'express'
import dotenv from 'dotenv';
import { connectDatabase } from './database/db.js';
import cors from 'cors'
import cookieParser from 'cookie-parser';
import userRoute from './routes/userRoute.js'
import bodyParser from 'body-parser';
const app=express();
dotenv.config()
const PORT=process.env.PORT || 5000

app.use(bodyParser.json())
app.use(express.json())
app.use(cors())
app.use(cookieParser())
app.use("/api/users", userRoute)

app.listen(PORT,()=>{
    connectDatabase()
    console.log(`server listening on port ${PORT}`)
})

middleware-

import jwt from 'jsonwebtoken'
import { User } from '../model/userModel.js'

export const protectRoute = async (req, res, next) => {

  
  try {
    const token = req.cookies.jwt   
    const decoded = jwt.verify(token, process.env.JWT_SECRET);

    const user = await User.findById(decoded.userid).select('-password');

    if (!user) {
      return res.status(401).json({ error: 'Unauthorized: User not found' });
    }

    req.user = user;
    console.log(user)
    next();
  } catch (error) {
    console.error("Error verifying JWT:", error.message);
    res.status(401).json({ error: 'Unauthorized: Invalid JWT' });
  }
};

when i am trying to send request from postman it works fine.

I am stuck with the problem .Please help me!

i want to inser data with image in react using axios

i want to inser data with image in react using axios but i hve problem

const useInsertDataWithImage = async (url, params) => {
  const config = {
    headers: { 'Content-Type': 'multipart/form-data' },
    Authorization: `Bearer ${localStorage.getItem('token')}`,
  };

  const res = await baseURL.post(url, params, config);
  console.log(res);
  return res.data;
};

here is my function
token is valid and it gives me

status:”Authorization Token not Found”
note it work in postman

i tried to mege url with params to pass only config but i cannot did it

How to write JS recursive function to trace sub-graphs, with adjacency list, for a list of initial nodes

Aim:

The aim is to develop a function that quickly traces sub-graphs for a list of nodes, given an existing adjacency list implementation, and returns a list of connected ID’s in addition to the original list

Problem

I am finding it hard to understand what to return, and how/where to add the found ID’s to the original list. The real issue is deciding:

  1. what the function returns,
  2. how to handle the two cases, recurse further or not

I have a skeleton code, but am starting at it not sure how to finish it off. Can you help please?

Adjacency List Class


//------------------------------------------
// Adjaceny List Class
//-------------------------------------------
class Graph {
  
  constructor(){
    this.adjacencyList = new Map();
  }

  addNode(node){
    this.adjacencyList.set(node, new Map());
  }

  addEdge(node1, node2){
    this.adjacencyList.get(node1).set(node2);
  }

  getNeighboors(node){
    return this.adjacencyList.get(node);
  }

  hasEdge(node1, node2){
    return this.adjacencyList.get(node1).has(node2);
  }

}

My half-finished skeleton

can anyone show me what to do with this please so it returns just the list of nodes in the sub-graphs, including the original ID’s? Thanks

function traceSubGraph(ID_list, adjacency) {
    let layer_IDs = []
    for (let ID in ID_list) {
        layer_IDs = adjacency.getNeighboors(ID);        
        if (layer_IDs.length) {
            // add new valid nodes to original list of nodes
            ID_list.concat(layer_IDs);
            // keep recursing, but how to add the new values?
            return traceSubGraph(layer_IDs, adjacency)            
        } 
        else {
          // stop recursing, what to do here?
        }
    }
  // what to return? ID_list, but where to add the new found nodes?
}

I had worked out that peering through the nodes and edges array was not fast, and then just manually using if/else to go down 3 or 4 layers was not good either. I then found this adjacency list class online. I have managed to fill it relatively easily, but it is using it to trace the subgraph that has me bedevilled.

Particularly the fact that we are iterating through a list, when we decide whether to recurse or not, makes it seem difficult for me as a noob.

I have tried looking at it for hours, and searching the web for tutorials on recursing, but i am still unsure as to the best approach.

How do I resolve an asynchronous load issue with JS?

I created a new portfolio project to host on my personal website with Kaboom.js and I’m having some issues getting it to load as intended. I suspect the issue is with the asynchronous nature of loading assets in Kaboom.js but so far I’ve been unsuccessful in resolving it.

The Project:
The visitor to the site walks around a house checking out different objects I’ve placed. Each object has a dialog box that gives information about my skills, resume, and qualifications. Imagine walking around a house in Pokémon Red. That’s the style and gameplay type. I used a sprite sheet and a map for the visuals.

Here is the code:

import { dialogData, scaleFactor } from "./constants";
import { k } from "./kaboomCtx";
import { displayDialog, setCamScale, openContactForm, closeContactForm } from "./utils";

document.addEventListener("DOMContentLoaded", () => {

    console.log('import.meta.url:', import.meta.url);

    console.log('Spritesheet URL:', new URL('../spritesheet.png', import.meta.url));
    k.loadSprite ("spritesheet", new URL ('../spritesheet.png', import.meta.url), {

        sliceX: 39,
        sliceY: 31,
        anims: {
            "idle-down": 936,
            "walk-down": { from: 936, to: 939, loop: true, speed: 8 },
            "idle-side": 975,
            "walk-side": { from: 975, to: 978, loop: true, speed: 8 },
            "idle-up": 1014,
            "walk-up": { from: 1014, to: 1017, loop: true, speed: 8 },
            "bag-open": 128,
        },
    });

    console.log('Map sprite URL:', new URL('../map.png', import.meta.url));
    k.loadSprite ("map", new URL ('../map.png', import.meta.url));

    k.load(() => {

        k.setBackground (k.Color.fromHex ("#311047"));

        // Creating a scene
        k.scene ("main", async () => {
            
            const mapJsonUrl = new URL('../map.json', import.meta.url);
            console.log('Map JSON URL:', mapJsonUrl);
            const mapData = await (await fetch(mapJsonUrl)).json();
            console.log('Map data:', mapData);
            const layers = mapData.layers;
            console.log('Layers:', layers);

            const map = k.add ([
                k.sprite ("map"),
                k.pos (0, 0),
                // Controls the scale size of the map -- see constants.js
                k.scale (scaleFactor)
            ]);

            const player = k.make ([
                k.sprite ("spritesheet", { anim: "idle-down" }),
                k.area ({ 
                    shape: new k.Rect (k.vec2(0, 3), 10, 10),
                }),
                k.body (),
                k.anchor ("center"),
                k.pos (),
                k.scale (scaleFactor),
                {
                    speed: 250,
                    direction: "down",
                    isInDialog: false,
                },
                "player",
            ]);

            for (const layer of layers) {
                if (layer.name == "Boundaries") {
                    for (const boundary of layer.objects) {
                        map.add ([
                            k.area ({
                                shape: new k.Rect (k.vec2(0), boundary.width, boundary.height),
                            }),
                            k.body ({isStatic: true}),
                            k.pos (boundary.x, boundary.y),
                            boundary.name,
                        ]);

                        if (boundary.name) {
                            player.onCollide(boundary.name, () => {
                                player.isInDialog = true;

                                displayDialog(
                                    dialogData[boundary.name],
                                    () => (player.isInDialog = false)
                                );
                            });
                        }
                    }
                    
                    continue;
                }

                if (layer.name == "Spawnpoint") {
                    for (const entity of layer.objects) {
                        if (entity.name == "player") {
                            player.pos = k.vec2(
                                (map.pos.x + entity.x) * scaleFactor,
                                (map.pos.y + entity.y) * scaleFactor
                            );
                            k.add(player);
                            continue;
                        }
                    }
                }
            }

            setCamScale(k)

            k.onResize(() => {
                setCamScale(k);
            });

            k.onUpdate(() => {
                k.camPos(player.pos.x, player.pos.y + 100);
            });

            // Player movement
            k.onMouseDown((mouseBtn) => {
                if (mouseBtn !== "left" || player.isInDialog)
                    return;

                const worldMousePos = k.toWorld(k.mousePos());
                player.moveTo(worldMousePos, player.speed);

                const mouseAngle = player.pos.angle(worldMousePos);
                const lowerBound = 50;
                const upperBound = 125;

                // Up
                if (mouseAngle > lowerBound && 
                    mouseAngle < upperBound && 
                    player.curAnim() !== "walk-up") {

                    player.play("walk-up");
                    player.direction = "up";
                    return;
                }

                // Down
                if (mouseAngle < -lowerBound &&
                    mouseAngle > -upperBound &&
                    player.curAnim() !== "walk-down") {

                    player.play("walk-down");
                    player.direction = "down";
                    return;
                    }

                // Right
                if (Math.abs(mouseAngle) > upperBound) {
                    player.flipX = false;

                    if (player.curAnim() !== "walk-side") {
                        player.play("walk-side");
                        player.direction = "right";
                        return;
                    }
                }

                // Left
                if (Math.abs(mouseAngle) < lowerBound) {
                    player.flipX = true;

                    if (player.curAnim() !== "walk-side") {
                        player.play("walk-side");
                        player.direction = "left";
                        return;
                    }
                }
            });

            // Stops walking animation
            k.onMouseRelease(() => {
                if (player.direction === "down") {
                    player.play("idle-down");
                    return;
                }

                if (player.direction === "up") {
                    player.play("idle-up");
                    return;
                }

                player.play("idle-side");
            });

            k.go ("main");
        });
    });
});

// Wait for the DOM to load before querying elements
window.addEventListener('DOMContentLoaded', (event) => {
    
    // Closes the contact form when the page loads
    closeContactForm();
    
    // Gets contact form buttons
    const openButton = document.querySelector('.ui-popup-button');
    const closeButton = document.querySelector('#closeContactFormButton');

    // Check if the elements exist before adding event listeners
    if (openButton) {
        openButton.addEventListener('click', openContactForm);
    } else {
        console.error("Element with class '.ui-popup-button' not found");
    }

    if (closeButton) {
        closeButton.addEventListener('click', closeContactForm);
    } else {
        console.error("Element with id 'closeContactFormButton' not found");
    }
});

And here is the error from the Chrome console:

Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLCanvasElement or HTMLImageElement or HTMLVideoElement or ImageBitmap or OffscreenCanvas or SVGImageElement or VideoFrame)'.
    at b.add (index-DfV-Wg4v.js:1:51115)
    at SpriteData.fromImage (index-DfV-Wg4v.js:1:66115)
    at Object.loadSprite (index-DfV-Wg4v.js:1:69732)
    at HTMLDocument.<anonymous> (index-DfV-Wg4v.js:1:136855)

A few things to note:

  1. The contact form functionality works. It’s the map and sprites that won’t show.

  2. As you can see in the code, I’ve added console.log code to check the status of certain variables. Only import.meta.url and spritesheet url fire in the console.

  3. I’ve tried window.onload and defer.

  4. If I take the assets and plug my website name into the path they load in the browser so I know the issue isn’t there.

  5. It did work fine testing locally but as usual, it’s a different ballgame when it comes to hosting.