Angular Tailwind v14 cant find image logo path

I’m using Angular 18 and Tailwind v14, and I have an issue with displaying images (such as a logo). When I set the correct path for the image, Angular can’t seem to find it.

The issue:

I correctly specify the image path in the tag, but it doesn’t display.

The same project worked fine with an older version of Tailwind (before the update).

Code snippets:

Here’s my angular.json configuration for assets:

"assets": [
  {
    "glob": "**/*",
    "input": "public"
  }
]

"styles": [
   "src/styles.css"
],

 "assets": [
{
  "glob": "**/*",
 "input": "public"
}
 ],
"styles": [
   "src/styles.css"
 ],

The image is located in the public folder.

What I’ve checked:

The image path seems correct (public/images/logo.png).

The image was displayed without issues in the older version of Tailwind.

I suspect the issue may be related to Tailwind (v14), but I’m not sure if it’s causing the problem.

Anyone facing the same issue or can point me in the right direction?

Automatic login with Windows user over JS/AngularJS front and C#/OWIN backend

I have a JavaScript/AngularJS fronted with C#/OWIN backend server.

Currently, users go to the login page and send their username/password via POST request and backend server returns a set of permissions for each screen (frontend has multiple tabs) in the GUI if the user is in the Active Directory and if it has an entry in some table.

Is is somehow possible to implement something that would automatically get the current Windows user credentials (username and password) and send it as soon as the login screen is opened (since JS cannot get those information)?

Since I’m not a C# nor a JS developer I tried to use chatGPT and other AI tools to get some info, but almost all sources contain some old code that’s currently obsolete.

Thanks

Lit rendering nested lists out of order?

I’m using Lit to render a nested list. If I push my list elements into an array with the sub-lists pushed as complete Lit html template objects then all is well, I can render the nested list with the template html`<ul>${myArray}</ul>` .

However, if I instead push sub-lists as their individual parts (<ul>, <li>Sub-First, …, </ul>) then the UL elements seem to get rendered out of order as <ul></ul><li>Sub-First.

Complete working example (assuming that you’ve got a copy of the Lit code as lit-all.min.js downloaded):

render-list.html

<!DOCTYPE html>
<html>
<head>
    <script type="module" src="render-list.js"></script>
</head>
<body>
    <render-list type="1"></render-list>
    <render-list type="2"></render-list>
</body>
</html>

render-list.js

import {LitElement, html} from "./lit-all.min.js";

export class RenderList extends LitElement {
    static properties = {
        type: {type: Number}
    };

    constructor() {
        super();
        this.type = 0;
    }

    render() {
        if (this.type == 1) {
            let lst = [];
            lst.push(html`<li>One`);
            lst.push(html`<li>Two`);
            let sublst = [];
            sublst.push(html`<li>Sublist One`);
            sublst.push(html`<li>Sublist Two`);
            lst.push(html`<ul>${sublst}</ul>`);
            lst.push(html`<li>Three`);
            return html`
                <h1>This list rendering works</h1>
                <ul>${lst}</ul>
            `;
        }
        else {
            let lst = [];
            lst.push(html`<li>One`);
            lst.push(html`<li>Two`);
            lst.push(html`<ul>`);
            lst.push(html`<li>Sublist One`);
            lst.push(html`<li>Sublist Two`);
            lst.push(html`</ul>`);
            lst.push(html`<li>Three`);
            return html`
                <h1>This list rendering doesn't work</h1>
                <ul>${lst}</ul>
            `;
        }
    }
}
customElements.define("render-list", RenderList);

This renders as below:

screenshot of browser

And looking in the developer tools shows the second list rendered as:

<ul>
<li>One
<li>Two
<ul></ul>
<li>Sublist One
<li>Sublist Two
<li>Three
<ul>

Clearly I’m not understanding something about the way Lit uses templates here. Why doesn’t the second solution work?

Why Dates are not compared in javascript? [duplicate]

I need to compare Date objects in JS but for some reason the comparison is not available in the standard version

new Date(1) == new Date(1) // return false

I tried converting dates to string format and it worked

new Date(1).toISOString() === new Date(1).toISOString() // return true

But I want to understand why the comparison of the standard Date format does not work


My guess is that the comparison returns “false” because it is not the date values ​​that are being compared, but the object references, even if that is the case I would like to know more about why this happens

Html load website and allow screen shot selection

i am trying to load website into html using js and allow screenshot

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Capture Screenshot</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
</head>
<body>
  <iframe id="iframe" src="https://stackoverflow.com/questions/31289275/how-to-get-screenshot-of-cross-domain-images-in-a-webpage" width="100%" height="500px"></iframe>
  <button id="capture">Capture Screenshot</button>
  <script>
    document.getElementById('capture').addEventListener('click', function() {
      var iframe = document.getElementById('iframe');
      html2canvas(iframe.contentWindow.document.body).then(function(canvas) {
        document.body.appendChild(canvas);
      });
    });
  </script>
</body>
</html>

but i am facing a cross-origin policy issues can i implement some proxy service which return the html and append it to current page so i can take screen shot?

Best way to parse json and extract attribute values dynamically in Angular [duplicate]

I am working new in Angular and working in a work where REST API returns a complex json entity and dynamically I have to fill html page components with values from the output json. The json structure will be like having mulltiple arrays in it. I need help with identifying json attributes at runtime by comparing json array fields, extract particular array item and attribute values from that and put into html component.
My JSON structure will be like below:

{
    "code": "0",
    "status": "SUCCESS",
    "hasError": false,
    "responsePayload": {
          ......
       "listOfParties": [
            {
                "role": "Primary Contact",
                "fullName": "John  Doe",
                "gender": "Male",
                "dateOfBirth": "01/01/1985",
                "partyCode": "PTYCODE01"
            },
            {
                "role": "Service Manager",
                "fullName": "Smith  Murphy",
                "gender": "Male",
                "partyCode": "PTYCODE02"
            }
        ],
      .......
}

From above json, I need to scan “listOfParties” and match “role” and after it matches with “Primary Contact”, need to get the “partyCode” and set it in input text in html page.

I have tried with: jsonObject[“listOfParties[0].partyCode”, but couldn’t get how to match it with “role” and then get “partyCode”. Can I do it with setting jsonPath or some better way to do it.

Thanks.

Cannot find native module ‘ExpoKioskControl’

I’m trying to implement kiosk mode in my Expo app using the expo-kiosk-control package.

I installed the package with:

npm install expo-kiosk-control
However, when I try to run my app, I get the following error:

Error: Cannot find native module ‘ExpoKioskControl’
I am using Expo SDK 52.

I am running the app with npx expo start.

Is there something I’m missing?
How can I fix this and properly use expo-kiosk-control in my project?

Thank you for your help!

How to Preview and Silently Print PDF (Blocking Virtual Printers) in Electron for a Pawning Management System?

I’m working on converting an existing CodeIgniter-based web pawning management system into a desktop app using Electron. My requirements are:

  1. PDF Preview: When printing, the user should see a preview of the
    PDF, but should NOT be able to save or download it.
  2. Silent Printing: The pawn ticket (PDF) should be printed directly to
    the default physical printer, with no print dialog shown.
  3. Block Virtual Printers: Virtual printers (like Microsoft Print to
    PDF, XPS, OneNote, etc.) must be blocked—only real/physical printers
    should be selectable.

What I’ve tried:

  • I can print HTML content silently using Electron (my test print
    works).
  • The actual ticket data comes as a PDF generated by CodeIgniter (using
    TCPDF).
  • When I try to print the PDF silently, nothing is printed, and I see
    errors like Printer settings invalid … content size is empty.

I have code to filter out virtual printers, but the main issue is reliably printing the PDF silently and showing a preview without allowing save/download.
Questions:

  1. How can I show a PDF preview in Electron but prevent the user from
    saving/downloading the file?
  2. What’s the best way to print a PDF silently to a physical printer in
    Electron (or another desktop framework), especially when the PDF is
    generated by a web backend?
  3. How can I ensure only physical printers are used (block all virtual
    printers) in the print dialog or silent print?

Any code samples, libraries, or architectural suggestions are appreciated!
The backend is CodeIgniter, generating PDFs with TCPDF.
I’m open to using other frameworks if Electron can’t do this reliably.

Start of main.js

const { app, BrowserWindow, ipcMain, shell } = 
require('electron');
const path = require('path');
const fs = require('fs');
const os = require('os');
const { net } = require('electron');

const DEBUG_MODE = true; // Set to false in production

let mainWindow;

// Create the main application window
function createWindow() {
mainWindow = new BrowserWindow({
width: 1280,
height: 800,
webPreferences: {
  nodeIntegration: false,
  contextIsolation: true,
  sandbox: false,
  preload: path.join(__dirname, 'preload.js')
},
autoHideMenuBar: true
});

// Load your web application
mainWindow.loadURL('http://192.168.1.17/pawn/pawn_sew/');

// Open external links in default browser
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
if (!url.startsWith('http://192.168.1.17')) {
  shell.openExternal(url);
  return { action: 'deny' };
}
return { action: 'allow' };
});
}

// Main app initialization
app.whenReady().then(() => {
createWindow();

// FIXED: Using correct API to get printers in newer Electron 
versions
setTimeout(() => {
try {
  // In newer versions of Electron, getPrinters is on 
webContents.getPrintersAsync()
  // or mainWindow.webContents.print.getPrinterList() depending 
on version
  if (mainWindow.webContents.getPrinters) {
    const printers = mainWindow.webContents.getPrinters();
    logPrinters(printers);
  } else if (mainWindow.webContents.getPrintersAsync) {
    mainWindow.webContents.getPrintersAsync().then(logPrinters);
  } else if (mainWindow.webContents.print && 
mainWindow.webContents.print.getPrinterList) {
    mainWindow.webContents.print.getPrinterList().then(logPrinters);
  }
} catch (err) {
  console.error('Failed to get printers:', err);
}
}, 2000); // Wait for window to be ready

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
  createWindow();
}
});
});

Codes related to printer selection

// Update the logPrinters function to show virtual printer status
function logPrinters(printers) {
  console.log('Available printers:');
  printers.forEach((printer, index) => {
    const isVirtual = isVirtualPrinter(printer.name);
    console.log(
      `${index + 1}. ${printer.name} (Default: ${printer.isDefault}, Virtual: ${isVirtual ? 'Yes' : 'No'})`
    );
  });
}

// Add this function to identify virtual printers
function isVirtualPrinter(printerName) {
  // Common virtual printer names (case-insensitive)
  const virtualPrinterPatterns = [
    /pdf/i,
    /microsoft/i,
    /adobe/i,
    /xps/i,
    /document writer/i,
    /onedrive/i,
    /fax/i,
    /virtual/i,
    /print to file/i,
    /cloud/i,
    /scan/i,
    /onenote/i,      // Added for OneNote
    /anydesk/i,      // Added for AnyDesk
    /remote/i,       // Common for remote printing solutions
    /universal/i,    // Often used in virtual print drivers
    /bullzip/i,      // Another common PDF printer
    /cutepdf/i,      // Common PDF printer
    /foxit/i,        // Foxit PDF printer
    /doro/i          // DoroEasy PDF
  ];
  
  return virtualPrinterPatterns.some(pattern => pattern.test(printerName));
}

// Add this helper function to determine if a printer is suitable for pawn tickets
function isSuitablePrinter(printerName) {
  const lowerName = printerName.toLowerCase();
  
  // Skip POS/thermal printers that aren't suitable for pawn tickets
  if (lowerName.includes('pos') || 
      lowerName.includes('thermal') || 
      lowerName.includes('receipt') || 
      lowerName.includes('dot matrix')) {
    console.log(`Skipping printer ${printerName} as it appears to be a thermal/POS printer`);
    return false;
  }
  
  // Include standard printers
  return true;
}

// Quit when all windows are closed (except on macOS)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

Pdf print related code (I used Chatgpt)

async function printWithWindows(pdfPath, printerName) {
  return new Promise((resolve, reject) => {
    const { exec } = require('child_process');
    // Use the Windows 'print' command (works for some printers, not all)
    // Note: This is a basic fallback and may not support all PDF features
    const command = `PRINT /D:"${printerName}" "${pdfPath}"`;
    exec(command, (error, stdout, stderr) => {
      if (error) {
        console.error(`Direct print error: ${error.message}`);
        reject(error);
      } else {
        console.log('Direct Windows print completed successfully');
        resolve(true);
      }
    });
  });
}

// Update the silent-print-ticket handler
ipcMain.handle('silent-print-ticket', async (event, ticketUrl) => {
  console.log('Received print request for:', ticketUrl);
  
  const DEBUG_MODE = true; // Set to false in production
  let tempPdfPath;
  let printWindow;
  
  try {
    // 1. Download PDF
    tempPdfPath = await downloadPdf(ticketUrl);
    
    // Verify file exists before printing
    if (!fs.existsSync(tempPdfPath)) {
      throw new Error(`PDF file does not exist at ${tempPdfPath}`);
    }

    const fileStats = fs.statSync(tempPdfPath);
    console.log(`PDF file size: ${fileStats.size} bytes`);
    
    // 2. Create a window with proper PDF display capabilities
    printWindow = new BrowserWindow({
      width: 800,
      height: 1100,
      show: DEBUG_MODE,
      webPreferences: {
        plugins: true
      }
    });
    
    if (DEBUG_MODE) {
      printWindow.webContents.openDevTools();
    }
    
    // 3. Load the PDF directly
    const pdfUrl = `file://${tempPdfPath.replace(/\/g, '/')}`;
    console.log(`Loading PDF from: ${pdfUrl}`);
    await printWindow.loadURL(pdfUrl);
    
    // Add event listeners to capture PDF loading issues
    printWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription) => {
      console.error(`Failed to load PDF: ${errorDescription} (${errorCode})`);
    });
    
    // 4. Give PDF time to render properly
    await new Promise(resolve => setTimeout(resolve, 2000));
    console.log('PDF loaded, preparing to print');
    
    // 5. Get available printers
    let printers = [];
    try {
      if (mainWindow.webContents.getPrinters) {
        printers = mainWindow.webContents.getPrinters();
      } else if (mainWindow.webContents.getPrintersAsync) {
        printers = await mainWindow.webContents.getPrintersAsync();
      } else if (mainWindow.webContents.print && mainWindow.webContents.print.getPrinterList) {
        printers = await mainWindow.webContents.print.getPrinterList();
      }
    } catch (err) {
      console.error('Failed to get printer list:', err);
      throw new Error('Could not find any printers. Please check your printer connection and try again.');
    }
    
    // 6. Filter out virtual printers and thermal printers
    const realPrinters = printers.filter(printer => 
      !isVirtualPrinter(printer.name) && isSuitablePrinter(printer.name)
    );
    console.log('Suitable printers for pawn tickets:', realPrinters.map(p => p.name));
    
    if (realPrinters.length === 0) {
      throw new Error('No suitable printers found for pawn tickets. Please connect a standard printer.');
    }
    
    // 7. Sort printers prioritizing default printers
    const sortedPrinters = [...realPrinters].sort((a, b) => {
      return a.isDefault ? -1 : (b.isDefault ? 1 : 0);
    });
    
    console.log('Prioritized printer order:', sortedPrinters.map(p => p.name));
    
    // 8. Try each printer until one succeeds - with standard Electron printing
    let lastError = null;
    for (const printer of sortedPrinters) {
      try {
        console.log(`Attempting to print to ${printer.name}...`);
        
        // Check network printer access
        if (printer.name.startsWith('\')) {
          const hasAccess = await checkPrinterAccess(printer.name);
          if (!hasAccess) {
            console.log(`No access to network printer: ${printer.name}, skipping...`);
            continue;
          }
        }
        
        // Try standard Electron print with A4 half portrait settings
        const printResult = await printWindow.webContents.print({
          silent: true,
          printBackground: true,
          deviceName: printer.name,
          pageSize: {
            width: 210000, // A4 width in microns
            height: 148500 // A4 height / 2 in microns
          },
          landscape: false,
          margins: {
            marginType: 'custom',
            top: 5000,
            bottom: 5000,
            left: 5000,
            right: 5000
          },
          dpi: {
            horizontal: 300,
            vertical: 300
          }
        });
        
        if (printResult) {
          console.log(`Successfully printed to ${printer.name}`);
          
          if (printWindow && !printWindow.isDestroyed()) {
            printWindow.close();
          }
          
          fs.unlink(tempPdfPath, () => {});
          
          return { 
            success: true, 
            printerName: printer.name,
            message: `Document successfully sent to printer "${printer.name}".`
          };
        } else {
          console.log(`Print to ${printer.name} returned false`);
          throw new Error('Printer returned unsuccessful status');
        }
      } catch (printerError) {
        console.error(`Failed to print to ${printer.name}:`, printerError.message);
        lastError = printerError;
        // Continue to next printer
      }
    }
    
    // 9. If Electron printing failed for all printers, try Windows direct printing
    console.log("All Electron print attempts failed. Trying Windows direct printing...");
    
    for (const printer of sortedPrinters) {
      try {
        console.log(`Attempting Windows direct print to ${printer.name}...`);
        await printWithWindows(tempPdfPath, printer.name);
        
        console.log(`Successfully printed to ${printer.name} using Windows direct printing`);
        
        if (printWindow && !printWindow.isDestroyed()) {
          printWindow.close();
        }
        
        return { 
          success: true, 
          printerName: printer.name,
          message: `Document successfully printed to "${printer.name}" using Windows direct printing.`
        };
      } catch (winError) {
        console.error(`Windows direct print to ${printer.name} failed:`, winError.message);
        // Continue to next printer
      }
    }
    
    // 10. Last resort: Show print dialog
    if (DEBUG_MODE) {
      console.log("All automatic print attempts failed. Trying with system dialog...");
      
      const dialogResult = await printWindow.webContents.print();
      
      if (dialogResult) {
        console.log("Print succeeded with system dialog");
        
        if (printWindow && !printWindow.isDestroyed()) {
          printWindow.close();
        }
        
        fs.unlink(tempPdfPath, () => {});
        
        return { 
          success: true, 
          message: "Document printed successfully using system dialog."
        };
      }
    }
    
    // If we get here, all methods failed
    throw new Error('All print methods failed. Please check your printer connections and try again.');
    
  } catch (error) {
    console.error('Print error:', error.message);
    if (printWindow && !printWindow.isDestroyed()) {
      printWindow.close();
    }
    if (tempPdfPath) {
      fs.unlink(tempPdfPath, () => {});
    }
    
    return { 
      success: false, 
      error: error.message,
      userFriendlyMessage: `Printing failed: ${error.message}. Please check your printer connections and try again.`,
      retryable: true
    };
  }
});

And this is the console outputs

Available printers:

  1. OneNote for Windows 10 (Default: false, Virtual: Yes)
  2. POS-80 (Default: false, Virtual: No)
  3. Microsoft XPS Document Writer (Default: false, Virtual: Yes)
  4. Microsoft Print to PDF (Default: false, Virtual: Yes)
  5. Fax (Default: false, Virtual: Yes)
  6. AnyDesk Printer (Default: false, Virtual: Yes)
  7. accounts-pcHP Ink Tank 310 series (Copy 1) (Default: true, Virtual: No) Received print request for:
    http://192.168.1.17/pawn/pawn_sew/swe_ticket.pdf PDF downloaded
    successfully (8038 bytes) PDF file size: 8038 bytes Loading PDF from:
    file://C:/Users/ADMINI~1/AppData/Local/Temp/ticket_1745819614508.pdf
    [10416:0428/112335.468:ERROR:CONSOLE(1)] “Request Autofill.enable
    failed. {“code”:-32601,”message”:”‘Autofill.enable’ wasn’t found”}”,
    source:
    devtools://devtools/bundled/core/protocol_client/protocol_client.js
    (1) [10416:0428/112335.468:ERROR:CONSOLE(1)] “Request
    Autofill.setAddresses failed.
    {“code”:-32601,”message”:”‘Autofill.setAddresses’ wasn’t found”}”,
    source:
    devtools://devtools/bundled/core/protocol_client/protocol_client.js
    (1) PDF loaded, preparing to print Skipping printer POS-80 as it
    appears to be a thermal/POS printer Suitable printers for pawn
    tickets: [ ‘\accounts-pcHP Ink Tank 310 series (Copy 1)’ ]
    Prioritized printer order: [ ‘\accounts-pcHP Ink Tank 310 series
    (Copy 1)’ ] Attempting to print to accounts-pcHP Ink Tank 310
    series (Copy 1)… Checking access to network path: accounts-pc
    Successfully accessed network path: accounts-pc Print to
    accounts-pcHP Ink Tank 310 series (Copy 1) returned false Failed to
    print to accounts-pcHP Ink Tank 310 series (Copy 1): Printer
    returned unsuccessful statused unsuccessful status All Electron print
    attempts failed. Trying Windows direct printing… …
    Attempting Windows direct print to accounts-pcHP Ink Tank 310
    series (Copy 1)…
    ows direct printing Direct Windows print completed successfully
    er: print_view_manager_base.cc:384 Printer settings invalid for
    accounts-pcH Successfully printed to accounts-pcHP Ink Tank 310
    series (Copy 1) using Windows direct printing
    [10416:0428/112337.075:ERROR:device_event_log_impl.cc(202)]
    [11:23:37.076] Printer: print_view_manager_base.cc:384 Printer
    settings invalid for accounts-pcHP Ink Tank 310 series (Copy 1)
    (destination type kLocal): content size is empty PS D:Softmaster
    ProjectsPawningpawn-electron-app>

Download blob PDF using Cypress

Here are my steps:

  1. Click a button
  2. A report is generated in new Tab as blob:https://myweburl/uuid and then downloaded.

I am using Cypress. After clicking the button, the PDF file opens in a new browser tab, and I can’t download the content automatically. Is there any way to force download the file instead of displaying the content in a new browser tab in Cypress?

I can’t download the content of the new window

Promise state is ‘fulfilled’ but showing 404 Not Found Error

I am sending user data to the backend using api. And i have problems with certain “skills”. Here in the image, in “skills” Array, when user selected’010308′, it shows 404 Not found error.
But I am quite confused about why only the certain skills are having error although ‘010301’ and ‘010308’ are almost the same – both are string without parameters. but ‘010301’ doesn’t have problems but ‘010308’ is having problem.
Moreover, the promise state become fulfilled but the message shows skill not found.
This is my code for sending data.

const updateResumeRequest = request({
url: /v1/user/resume/${rid}/update,
method: ‘post’,
headers: {
Authorization: Bearer ${token},
},
data: parseRequestData(data),
});
console.log(‘parserequestdata data’, parseRequestData(data))
console.log(‘updateresumerequest’, updateResumeRequest)

Console image

How to set an initial value to PlaceAutocompleteElement

I am creating an autocomplete address input element via google.maps.places.PlaceAutocompleteElement, to let users autocomplete addresses.

The thing is that users have previously saved their address in our database, so I need to set the PlaceAutocompleteElement input an initial address value, but it seems it is impossible.

I have read the documentation about the different options that can be passed, but found nothing to set an initial value to the input.

How can I set an initial value to the input element created with google.maps.places.PlaceAutocompleteElement??

Thank you so much!

How to close dialog in React?

I have a general DialogueWindow component:

function DialogueWindow({elements}) {

  return (

    <div className="backdrop">

      <dialog className="dialogue-window">

        {elements}

      </dialog>

    </div>
  )
}

export default DialogueWindow

It displays inside of it whatever elements it gets passed down to. Currently I’m passing on a FileUploader element, that has a cancel button for the user to close the dialog.

In App.js:

<DialogueWindow
     elements={
        <FileUploader/>
     }
/>

In FileUploader:

function FileUploader() {

  ...

  return (

    <div className="file-uploader">

        ...

        <div className="file-uploader-button-container">

            <button>
                Upload
            </button>

            <button>
                Cancel
            </button>

        </div>

    </div>
  )
}

export default FileUploader

I have seen that in standard javascript you call document.getElementById() to fetch the dialog element, and then call the close() method on it. But how does this work in React?

Next.js multi-zones assets is not working

I want to build nextjs app that gonna be served like a SaaS, so i have a main team that gonna develop this apps, and another division team that gonna join development with us,

My project structure gonna look like this

src

  • -/app
      • -/services1
      • -/services2
  • -/sub-app
      • -/services-sub-app

i’m looking to build it using Next.js Multi-zones feature, but i have some issues while building it.

I managed to connect the main app to the sub-app using next.config.ts rewrites on the main app like this.

const nextConfig: NextConfig = {
    // For Static Export
    output: "standalone",
    basePath: "/app",
    assetPrefix: "/app",
    images: {
        unoptimized: true,
    },
    async rewrites() {
        return [
            {
                source: `/ppsdm`,
                destination: `http://localhost:3001/ppsdm`,
            },
            {
                source: `/ppsdm/:path*`,
                destination: `http://localhost:3001/ppsdm/:path*`,
            },
            {
                source: `/ppsdm-static/_next/:path*`,
                destination: `http://localhost:3001/ppsdm-static/_next/:path*`,
            },
        ];
    },
};

and next.config.ts on the sub-app like this

const nextConfig: NextConfig = {
    /* config options here */
    basePath: "/ppsdm",
    assetPrefix: "/ppsdm-static",
};

the routing works just fine, but the sub-app assets and styles it not working, it got a lot of 404 not found on the console like on the image i attached.

enter image description here

when i try to manually open the link on the console, let’s say this one
http://localhost:3000/ppsdm-static/_next/static/chunks/%5Broot-of-the-server%5D__8ebb6d4b._.css
it returns 404 Not Found.

but when i added “app” in front of the ppsdm-static, it works just fine
http://localhost:3000/app/ppsdm-static/_next/static/chunks/%5Broot-of-the-server%5D__8ebb6d4b._.css

What could be wrong?

Why does the window move when the user makes a selection?

In our JavaScript Vue code we have a template that looks approximately like this:

<template>
  <NiceDialog
    ref="selectMenuBody"
    closable
    modal
    v-model:visible="visible"
    :header="title"
    style="min-width: 35rem; width: auto"
    @keydown.escape.exact.stop.prevent="doHide"
    @keydown.space.stop.prevent=""
    @hide="doHide"
    @dragend="dragEnd"
    @mousedown="dragging = true"
  >
    <div class="ml-1">Charset:</div>
    <select v-model="selected" style="width: calc(100% - 0.4rem); margin: 0.2rem; height: 1.75rem">
      <option v-for="o in listItems" :key="o">{{ o }}</option>
    </select>
    <table>
      <tbody>
        <tr v-for="m in 8" :key="m - 1">
          <td v-for="n in 16" :key="(m - 1) * 16 + n - 1">
            <button
              @click.stop="_clickButton(charIfPrintable(m, n))"
              style="width: 3.3rem; height: 2.2rem"
              onclick="this.blur();"
            >
              {{ charIfPrintable(m, n) }}
            </button>
          </td>
        </tr>
      </tbody>
    </table>
  </NiceDialog>
</template>

What bothers us is that when we move the window and then make a selection in the select box, the position of the window is modified. It’s not like it jumps back to a default position but the position is simply changed a bit. We would like to make the position static. How can this be done?

Twilio WhatsApp Template – Dynamic Media URL and Button URL Not Working

I’m working on Twilio’s WhatsApp Business API integration using an approved message template.

The template includes:

Dynamic body fields (like product title, color, price)

A Header (Image)

A Button (with URL)

I am sending the WhatsApp message using Twilio’s Content API, passing dynamic values like this:

await twilioClient.messages.create({
from: whatsapp:${twilioPhoneNumber},
to: whatsapp:+${formattedPhoneNumber},
contentSid: process.env.TWILIO_CONTENT_TEMPLATE_SID,
contentVariables: JSON.stringify({
‘1’: title,
‘2’: color,
‘3’: price,
‘4’: imageUrl, // Dynamic image URL
‘5’: productUrl // Dynamic button URL
})
});
Current Situation:

The Body text fields (title, color, price) are being dynamically replaced correctly.

But the Header Image and Button URL are still showing the static URLs that were submitted during template approval, even though I pass dynamic values in code.

What I Expected:

I expected Twilio and WhatsApp to replace the media (image) and button URL with the dynamic values sent through contentVariables.

What Actually Happened:

Only body text changes dynamically.

Header Image and Button URL remain static — same as the original template content.

Research Summary:
After deep research, it looks like WhatsApp Business API currently does NOT support dynamic media URLs (Header) or dynamic button URLs at runtime.
Both media and buttons must be fixed (static) at the time of template creation and approval.

Only text placeholders in the Body are supported as dynamic values during message sending.

Question:

Is there any known workaround to make media URL and button URL dynamic at runtime on Twilio?

Or is this 100% a WhatsApp Business API limitation?

Progress Update:

I created multiple templates, tested with valid HTTPS URLs.

I’m passing all required dynamic values correctly via contentVariables.

No more 63005 or validation errors now.

The body text is dynamic, but media and button links remain static.

Thanks in advance!