fix(navigation): respect BASE_URL in tool pages and navbar brand (Fixes #850)

This commit is contained in:
nipunrajk
2026-09-26 09:22:15 +05:30
parent daae736907
commit 90fe106664
7 changed files with 113 additions and 18 deletions
+1 -1
View File
@@ -60,7 +60,7 @@
class="h-8 w-8"
/>
<span class="text-white font-bold text-xl ml-2">
<a href="/"
<a href="{{baseUrl}}"
>{{#if brandName}}{{brandName}}{{else}}BentoPDF{{/if}}</a
>
</span>
+1 -1
View File
@@ -273,7 +273,7 @@ function initPage(): void {
if (backBtn) {
backBtn.addEventListener('click', () => {
window.location.href = '/';
window.location.href = import.meta.env.BASE_URL;
});
}
+1 -1
View File
@@ -311,6 +311,6 @@ document.addEventListener('DOMContentLoaded', () => {
processBtn?.addEventListener('click', processAndDownloadForm);
backBtn?.addEventListener('click', () => {
window.location.href = '../../index.html';
window.location.href = import.meta.env.BASE_URL;
});
});
+13 -13
View File
@@ -1,21 +1,21 @@
import { MarkdownEditor } from '../utils/markdown-editor.js';
document.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('markdown-editor-container');
const container = document.getElementById('markdown-editor-container');
if (!container) {
console.error('Markdown editor container not found');
return;
}
if (!container) {
console.error('Markdown editor container not found');
return;
}
const editor = new MarkdownEditor(container, {});
const editor = new MarkdownEditor(container, {});
console.log('Markdown editor initialized');
console.log('Markdown editor initialized');
const backButton = document.getElementById('back-to-tools');
if (backButton) {
backButton.addEventListener('click', () => {
window.location.href = '/';
});
}
const backButton = document.getElementById('back-to-tools');
if (backButton) {
backButton.addEventListener('click', () => {
window.location.href = import.meta.env.BASE_URL;
});
}
});
+1 -1
View File
@@ -189,6 +189,6 @@ document.addEventListener('DOMContentLoaded', () => {
processBtn?.addEventListener('click', processRemoveAnnotations);
backBtn?.addEventListener('click', () => {
window.location.href = '../../index.html';
window.location.href = import.meta.env.BASE_URL;
});
});
+1 -1
View File
@@ -366,6 +366,6 @@ document.addEventListener('DOMContentLoaded', () => {
processBtn?.addEventListener('click', processRemoveBlankPages);
document.getElementById('back-to-tools')?.addEventListener('click', () => {
window.location.href = '../../index.html';
window.location.href = import.meta.env.BASE_URL;
});
});
+95
View File
@@ -0,0 +1,95 @@
import { describe, it, expect } from 'vitest';
import * as fs from 'fs';
import * as path from 'path';
describe('Navigation BASE_URL Consistency', () => {
const logicDir = path.resolve(__dirname, '../js/logic');
const pagesDir = path.resolve(__dirname, '../pages');
const rootDir = path.resolve(__dirname, '../../');
it('ensures no tool logic files hardcode root "/" or relative paths for navigation', () => {
const files = fs
.readdirSync(logicDir)
.filter((file) => file.endsWith('.ts') || file.endsWith('.js'));
const offendingFiles: string[] = [];
for (const file of files) {
const content = fs.readFileSync(path.join(logicDir, file), 'utf-8');
// Check for hardcoded root redirects or relative path escapes
if (
/window\.location\.href\s*=\s*['"`]\/['"`]/.test(content) ||
/window\.location\.href\s*=\s*['"`]\.\.\//.test(content)
) {
offendingFiles.push(file);
}
}
expect(
offendingFiles,
`The following files hardcode root or relative navigation instead of import.meta.env.BASE_URL: ${offendingFiles.join(
', '
)}`
).toEqual([]);
});
it('ensures tool logic files with back-to-tools button use import.meta.env.BASE_URL', () => {
const files = fs
.readdirSync(logicDir)
.filter((file) => file.endsWith('.ts') || file.endsWith('.js'));
const filesMissingBaseUrl: string[] = [];
for (const file of files) {
const content = fs.readFileSync(path.join(logicDir, file), 'utf-8');
// If the file handles 'back-to-tools' click navigation
if (
content.includes('back-to-tools') &&
content.includes('window.location.href') &&
!content.includes('import.meta.env.BASE_URL')
) {
filesMissingBaseUrl.push(file);
}
}
expect(
filesMissingBaseUrl,
`The following files handle back-to-tools navigation without import.meta.env.BASE_URL: ${filesMissingBaseUrl.join(
', '
)}`
).toEqual([]);
});
it('ensures HTML templates do not hardcode href="/" for brand links', () => {
const htmlFiles = fs
.readdirSync(pagesDir)
.filter((file) => file.endsWith('.html'))
.map((file) => path.join(pagesDir, file));
const simpleIndex = path.join(rootDir, 'simple-index.html');
if (fs.existsSync(simpleIndex)) {
htmlFiles.push(simpleIndex);
}
const offendingFiles: string[] = [];
for (const filePath of htmlFiles) {
const content = fs.readFileSync(filePath, 'utf-8');
// Brand link / logo anchor should not be hardcoded to href="/"
// e.g. <a href="/"> should be <a href="{{baseUrl}}">
if (/<a\s+[^>]*href=["']\/["'][^>]*>.*BentoPDF/i.test(content)) {
offendingFiles.push(path.basename(filePath));
}
}
expect(
offendingFiles,
`The following HTML templates hardcode href="/" for the brand link: ${offendingFiles.join(
', '
)}`
).toEqual([]);
});
});