Skip to content

Allow serving the GUI from a subdirectory#520

Merged
marc-vanderwal merged 1 commit into
zonemaster:releases/ssg-standalone-componentsfrom
marc-vanderwal:bugfix/gui-from-subdirectory
Dec 15, 2025
Merged

Allow serving the GUI from a subdirectory#520
marc-vanderwal merged 1 commit into
zonemaster:releases/ssg-standalone-componentsfrom
marc-vanderwal:bugfix/gui-from-subdirectory

Conversation

@marc-vanderwal

@marc-vanderwal marc-vanderwal commented Dec 9, 2025

Copy link
Copy Markdown
Contributor

Purpose

This PR makes some modifications so that the GUI can be served from a non-root path, such as https://zonemaster.example/some/subdirectory.

Context

Release testing for 2025.2.

Changes

  • Adjust Apache example configuration file.
  • Add a configuration item in config.ts and use it in astro.config.mjs.
  • Some adjustments in Astro and Svelte files/templates in order

How to test this PR

Assuming there is already a GUI installed on your machine:

  1. Edit config.ts and override the baseUrl (e.g. baseUrl: "/some/subdirectory") and the apiBaseUrl (e.g. apiBaseUrl: "/some/subdirectory/api").
  2. Run npm run release to build the GUI.
  3. Replace the files in /var/www/html/zonemaster-web-gui with the contents of the newly-generated ZIP file.
  4. Replace the Apache configuration file (/etc/apache2/sites-enabled/zonemaster.conf) with the newly-generated example file (/var/www/html/zonemaster-web-gui/zonemaster.conf-example).
  5. Edit the Apache configuration file. Uncomment the line starting with Define BASE_URL and set BASE_URL to "/some/subdirectory".
  6. Reload Apache.
  7. Navigate to https://your.hostname.example/some/subdirectory. The GUI should load without errors. Check in your browser’s developer console that there are no errors either. Also try running a test and selecting tests in the domain’s test history.

@matsduf

matsduf commented Dec 9, 2025

Copy link
Copy Markdown
Contributor

When this works, "Simple build-time configuring Zonemaster-GUI using 'config.ts'" in zonemaster/zonemaster#1442 must be updated correct instructions.

@matsduf

matsduf commented Dec 9, 2025

Copy link
Copy Markdown
Contributor

@tbleckert and @rhedman, do you see any issues with the solution in this PR?

@marc-vanderwal marc-vanderwal force-pushed the bugfix/gui-from-subdirectory branch 2 times, most recently from b059087 to b8cee3e Compare December 9, 2025 12:59
@matsduf

matsduf commented Dec 9, 2025

Copy link
Copy Markdown
Contributor
  1. Run npm run release to build the GUI.

Not npm run build first? Or is that done automatically?

@matsduf

matsduf commented Dec 9, 2025

Copy link
Copy Markdown
Contributor

Are the changes in src/layouts/BaseLayout.astro is to resolve the bug with missing favicon only? Or is it related to the core issue of this PR?

Comment thread zonemaster.conf-example Outdated
@tgreenx tgreenx added V-Patch Versioning: The change gives an update of patch in version. RC-None Release category: Not to be included in Changes file. labels Dec 9, 2025
@MichaelTimbert MichaelTimbert added RC-None Release category: Not to be included in Changes file. and removed RC-None Release category: Not to be included in Changes file. labels Dec 9, 2025
Comment thread zonemaster.conf-example Outdated
@tbleckert

Copy link
Copy Markdown
Contributor

@tbleckert and @rhedman, do you see any issues with the solution in this PR?

I don't see any issues, looks good!

@marc-vanderwal

Copy link
Copy Markdown
Contributor Author

Not npm run build first? Or is that done automatically?

npm run release is defined as npm run build && node scripts/create_release.js, so yes, it is fine to only run npm run release.

Are the changes in src/layouts/BaseLayout.astro is to resolve the bug with missing favicon only? Or is it related to the core issue of this PR?

Sort of both. While fixing the issue addressed in this PR, I was trying to use the <base> element and I might have changed the favicon URLs then. Just to make sur that everything is loaded from a location within the subdirectory. While related to the ability for the GUI to be served from a subdirectory, it is also an unintended fix of issue #515.

@matsduf

matsduf commented Dec 10, 2025

Copy link
Copy Markdown
Contributor
1. Edit `config.ts` and override the `baseUrl` (e.g. `baseUrl: "/some/subdirectory"`) and the `apiBaseUrl` (e.g. `apiBaseUrl: "/some/subdirectory/api"`).

Is it possible to change so that apiBaseUrl is automatically adjusted to match updated baseUrl so that we can have one instead of two steps here?

Comment thread zonemaster.conf-example
Comment thread zonemaster.conf-example Outdated
@marc-vanderwal

Copy link
Copy Markdown
Contributor Author

Is it possible to change so that apiBaseUrl is automatically adjusted to match updated baseUrl so that we can have one instead of two steps here?

Maybe. But the release time is approaching quickly and I do not want to introduce any more changes than necessary. I am not familiar enough with JavaScript or TypeScript to implement such a change.

But your suggestion on the Apache configuration file looks good. I’ll implement it.

Comment thread zonemaster.conf-example Outdated
Comment thread zonemaster.conf-example
Comment thread zonemaster.conf-example
@marc-vanderwal

Copy link
Copy Markdown
Contributor Author

I’m not sure these suggestions are going to work. I tried going the <If> route previously but Apache did not like me setting DocumentRoot in an If block and rejected the configuration file with a somewhat cryptic error message.

There is a big difference between If and IfDefine blocks: If blocks are evaluated at each request, while IfDefine is evaluated when the configuration is being parsed. As far as I know, I can’t use anything else but IfDefine here.

@marc-vanderwal

Copy link
Copy Markdown
Contributor Author

Tried it, and Apache rejects the configuration file:

apachectl[1606]: AH00526: Syntax error on line 11 of /etc/apache2/sites-enabled/zonemaster.conf:
apachectl[1606]: Cannot parse condition clause: Variable 'BASE_URL' does not exist
apachectl[1596]: Action 'start' failed.
apachectl[1596]: The Apache error log may have more information.

@matsduf

matsduf commented Dec 10, 2025

Copy link
Copy Markdown
Contributor

I got a new suggestion from ChatGTP:

# Update this if the GUI is served from a subdirectory.
# Must start with a slash, no trailing slash.
Define BASE_URL "/"

# Serve the GUI (works for "/" and subdirs).
Alias "${BASE_URL}" "/var/www/html/zonemaster-web-gui/dist"

# --- API base URL as an *environment* variable ---

# Default when BASE_URL = "/"
SetEnv API_BASE_URL "/api"

# If BASE_URL is not "/", use "<base>/api"
<If "'${BASE_URL}' != '/'">
    SetEnv API_BASE_URL "${BASE_URL}/api"
</If>

I will check.

@matsduf

matsduf commented Dec 10, 2025

Copy link
Copy Markdown
Contributor

I will suggest a new conf file, if successful.

@marc-vanderwal marc-vanderwal force-pushed the bugfix/gui-from-subdirectory branch from 374555a to 55190e3 Compare December 10, 2025 13:12

@tgreenx tgreenx left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but I haven't tested it yet.

@MichaelTimbert MichaelTimbert left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested on Rocky 8, work fine.

@matsduf matsduf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works when testing with a subdirectory, but it does not work when just using as-is. @MichaelTimbert, did you test without subdirectory?

Secondly, I hope to have an configuration where you should change fewer things.

@MichaelTimbert MichaelTimbert left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried again today, and it works in both cases, with or without a subdirectory. The important thing is not to forget to rebuild the zonemaster-gui zip file from the source code, because you need to modify the config.ts file.

@matsduf

matsduf commented Dec 12, 2025

Copy link
Copy Markdown
Contributor

I propose the following to replace zonemaster.conf-example in the PR. In my proposal you only have to change one variable to change subdirectory and it is more concise. Also submitted as proposals below.

<VirtualHost *:80>

    # BASE_URL can be set and DEFAULT_LANGUAGE can be updated.

    # Uncomment the following line *only* if the GUI is served from a
    # subdirectory. The setting here must match the setting in config.ts.
    # Must start with a slash, but not end with a slash.
    # Define BASE_URL "/subdirectory" # Undefined by default

    # Default language must be updated if "defaultLanguage" in config.ts is
    # changed. Both must match.
    Define DEFAULT_LANGUAGE "en"


    # Nothing to set or update below. #

    DirectoryIndex index.html
    
    <IfDefine BASE_URL>
        Alias ${BASE_URL} /var/www/html/zonemaster-web-gui/dist
        Define API_BASE_URL "${BASE_URL}/api"
    </IfDefine>

    <IfDefine !BASE_URL>
        DocumentRoot /var/www/html/zonemaster-web-gui/dist
        Define API_BASE_URL "/api"
    </IfDefine>

    <Directory /var/www/html/zonemaster-web-gui/dist>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted

        RewriteEngine On
        <IfDefine BASE_URL>
            RewriteBase ${BASE_URL}/
        </IfDefine>

        # Rewrite /result/{anything} to {default_language}/result/id/index.html
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^result/[^/]+/?$ ${DEFAULT_LANGUAGE}/result/id/index.html [L]

        # Rewrite /{lang}/result/{anything} to /{lang}/result/id/index.html
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^([^/]+)/result/[^/]+/?$ $1/result/id/index.html [L]
    </Directory>

    <Location "${API_BASE_URL}">
        ProxyPass http://localhost:5000/
        ProxyPassReverse http://localhost:5000/
        ProxyPreserveHost On
    </Location>
</VirtualHost>

@matsduf

matsduf commented Dec 12, 2025

Copy link
Copy Markdown
Contributor

I have tested my proposal both with and without subdirectory and for me it has worked correctly.

Else things works well and I have updated the documentation accordingly (see zonemaster/zonemaster@d9fb884).

matsduf added a commit to matsduf/zonemaster that referenced this pull request Dec 12, 2025
matsduf added a commit to matsduf/zonemaster that referenced this pull request Dec 12, 2025
matsduf added a commit to matsduf/zonemaster that referenced this pull request Dec 12, 2025
Comment thread zonemaster.conf-example Outdated
Comment thread zonemaster.conf-example Outdated
Comment thread zonemaster.conf-example Outdated
In order to support use cases where the GUI is served from a non-root
base URL (i.e. https://zonemaster.example/some/subdirectory instead of
https://zonemaster.example), some modifications were necessary to some
Astro and Svelte files in the project.

I initially tried to keep my modifications to the Apache configuration
files without touching anything else, but I quickly realized that it
couldn’t be done by editing Apache configuration files alone. That is
because the build process assumes that the site is served from a base
directory of / and all HTML files have baked-in absolute URLs.

Fortunately, astro.config.mjs allows setting a base path that can be
easily referred to from Astro and Svelte files. Setting it
fixed *almost* everything: CSS and JS assets load from the right place,
but favicons did not and some link target URLs needed manual adjustment
in order to include the base directory.

I am not familiar with these technologies and there might be a better
approach to some of the edits I’ve made to Astro and Svelte files.

So instead of having to edit the Apache configuration file, one needs to
edit that file and config.ts in order to set the base URL to a
non-default value. This seems to me like an acceptable compromise.
@marc-vanderwal marc-vanderwal force-pushed the bugfix/gui-from-subdirectory branch from 55190e3 to 1a1f739 Compare December 15, 2025 07:35
@marc-vanderwal

Copy link
Copy Markdown
Contributor Author

I propose the following to replace zonemaster.conf-example in the PR. In my proposal you only have to change one variable to change subdirectory and it is more concise. Also submitted as proposals below.

Okay, thanks for the proposal! I’ve committed it in the latest iteration.

@marc-vanderwal marc-vanderwal merged commit f415d0a into zonemaster:releases/ssg-standalone-components Dec 15, 2025
1 check passed
@marc-vanderwal marc-vanderwal mentioned this pull request Dec 15, 2025
@tgreenx tgreenx linked an issue Dec 22, 2025 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

RC-None Release category: Not to be included in Changes file. V-Patch Versioning: The change gives an update of patch in version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New GUI loads favicons from wrong location

5 participants