Recompiled modern app in different path fails to call server api

gustavofarias2 years ago

I'm trying to run Traccar 5.6 on a non root path, like https://mydomain.com/gps

To do that I'm following this: https://www.traccar.org/secure-connection/

It reads: "Note that you also need to recompile the modern app for it to work correctly on a new path."

This leads me to here: https://www.traccar.org/build-web-app/

I did:

npm install
npm run build

the console spit:

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

I assumed this is what I need to do.

So I put in package.json:

{
  "name": "traccar",
  "version": "5.6.0",
  "private": true,
  "homepage": "https://mydomain.com/gps",
  "dependencies": {
 (...)
gustavofarias2 years ago

Continuation... (I think the forum has a character limit)

This time I got:

The project was built assuming it is hosted at /gps/.
You can control this with the homepage field in your package.json.

Then I uploaded the contents of traccar-web/modern/build to the /opt/traccar/modern folder of the server.

When I browse https://mydomain.com/gps server correctly returns index.html which in turn correctly references main.xyz.js, main.xyz.css, styles.css, stuff in static/media etc. I see the purple loading bar in the top. Everything seems fine.

Then a call to https://mydomain.com/api/server (no /gps/ part) is made by ServerProvider.js line 19:

(...)
  useEffectAsync(async () => {
    if (!error) {
      try {
        const response = await fetch('/api/server');         <--- this line
        if (response.ok) {
          dispatch(sessionActions.updateServer(await response.json()));
        } else {
          throw Error(await response.text());
        }
(...)

This call obviously can't work. What should I do to fix it?

Anton Tananaev2 years ago

You should replace all /api/*** calls with /gps/api/***.

gustavofarias2 years ago

I've found 154 occurrences. Some are very similar. Below I left only the distinct ones.
Which ones should I change?
How do I know if some of those will be corrected by the build? The first two have this REACT_APP_URL_NAME.

app.use(createProxyMiddleware('/api/socket', { target: `ws://${process.env.REACT_APP_URL_NAME}`, ws: true }));
app.use(createProxyMiddleware('/api', { target: `http://${process.env.REACT_APP_URL_NAME}` }));
await fetch('/api/permissions/bulk', {
await fetch(`/api/session?token=${encodeURIComponent(token)}`);
const response = await fetch('/api/users', {
const response = await fetch(`/api/${endpoint}/${id}`);
const socket = new WebSocket(`${protocol}//${window.location.host}/api/socket`);
const url = `/api/attributes/computed/test?${query.toString()}`;
endpoint="/api/calendars"
endpoint={`/api/commands/send?deviceId=${deviceId}`}
endpoint={deviceId ? `/api/commands/types?${new URLSearchParams({ deviceId }).toString()}` : '/api/commands/types'}
endpointAll="/api/attributes/computed"
endpointLinked={`/api/attributes/computed?deviceId=${item.id}`}
if (url.pathname.startsWith('/api/')) {
image={`/api/media/${device.uniqueId}/${deviceImage}`}
let url = `/api/${endpoint}`;
results.push(fetch('/api/permissions', {
return (<Link href={`/api/media/${devices[item.deviceId]?.uniqueId}/${item.attributes.file}`} target="_blank">{item.attributes.file}</Link>);
window.location.assign(`/api/reports/trips/xlsx?${query.toString()}`);
Anton Tananaev2 years ago

Probably all of them. Obviously you should check each usage to make sure it's correct.

gustavofarias2 years ago

those too?

app.use(createProxyMiddleware('/api/socket', { target: `ws://${process.env.REACT_APP_URL_NAME}`, ws: true }));
app.use(createProxyMiddleware('/api', { target: `http://${process.env.REACT_APP_URL_NAME}` }));
gustavofarias2 years ago

Have you ever seen any real instance of this "non root path" thing working?
It seems this "Traccar in subdirectory (non root path)" is just a remnant from legacy app that you appended this
"you also need to recompile the modern app for it to work" but never really thought would work or be needed/tried.

Anton Tananaev2 years ago

I know a couple of clients who use it with a non root path and it's working fine. It's definitely more work than doing it with the old app. That's why I keep recommending a subdomain instead.

gustavofarias2 years ago

Changed /api/*** calls with /gps/api/***.

The error is gone, every call to the server is a hit now. Purple loading bar in the top, but I get only a blank screen. The source code of the black screen is index.html.