diff --git a/backend/src/services/sitemapService.js b/backend/src/services/sitemapService.js
index bbf1b28..5e044aa 100644
--- a/backend/src/services/sitemapService.js
+++ b/backend/src/services/sitemapService.js
@@ -85,7 +85,7 @@ const siteMapService = {
sitemap += ``;
// Write sitemap to file
- const publicDir = path.join(__dirname, '../../public');
+ const publicDir = path.join(__dirname, '../../public/seo-files');
if (!fs.existsSync(publicDir)) {
fs.mkdirSync(publicDir, { recursive: true });
}
diff --git a/docker-compose.yml b/docker-compose.yml
index 355c85c..976fb44 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -11,6 +11,7 @@ services:
volumes:
- ./frontend:/app
- /app/node_modules
+ - seo-volume:/app/public
depends_on:
- backend
networks:
@@ -28,7 +29,8 @@ services:
volumes:
- ./backend:/app
- /app/node_modules
- - ./backend/public/uploads:/app/public/uploads # Persist uploads
+ - ./backend/public/uploads:/app/public/uploads
+ - seo-volume:/app/public/seo-files
depends_on:
db:
condition: service_healthy
@@ -102,6 +104,7 @@ services:
volumes:
postgres_data:
redis_data:
+ seo-volume:
networks:
app-network:
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 2556ca2..75203b4 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -8,7 +8,6 @@ import useBrandingSettings from '@hooks/brandingHooks';
import imageUtils from '@utils/imageUtils';
import Clarity from '@microsoft/clarity';
import CookieConsentPopup from '@components/CookieConsentPopup';
-import SeoProxyRoutes from '@components/SeoProxyRoutes';
// Import layouts
import MainLayout from './layouts/MainLayout';
@@ -133,9 +132,6 @@ function App() {
- {/* SEO Routes for sitemap.xml and robots.txt */}
-
-
{/* Main routes with MainLayout */}
}>
diff --git a/frontend/src/components/SeoProxyRoutes.jsx b/frontend/src/components/SeoProxyRoutes.jsx
deleted file mode 100644
index 76c92c6..0000000
--- a/frontend/src/components/SeoProxyRoutes.jsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import { Routes, Route } from 'react-router-dom';
-import axiosClient from '@services/seoapi';
-
-/**
- * Component to serve SEO files (sitemap.xml, robots.txt) directly from API
- */
-const SeoFile = ({ filePath }) => {
- const [content, setContent] = useState('');
- const [contentType, setContentType] = useState('');
- const [error, setError] = useState(null);
- console.log(filePath)
- useEffect(() => {
- // Determine the content type based on the file extension
- const fileExtension = filePath.split('.').pop();
- const type = fileExtension === 'xml' ? 'application/xml' : 'text/plain';
- setContentType(type);
-
- // Fetch the file from the API
- axiosClient.get(filePath, {
- responseType: 'text',
- headers: {
- 'Accept': type
- }
- })
- .then(response => {
- setContent(response.data);
- })
- .catch(err => {
- console.error(`Error fetching ${filePath}:`, err);
- setError(`Error loading ${filePath}. ${err.message}`);
- });
- }, [filePath]);
-
- // Set the content type and return the raw content
- useEffect(() => {
- if (content && contentType) {
- // Clear existing document
- document.open();
-
- if (contentType.includes('xml')) {
- // For XML sitemaps, just write the raw content directly
- // This is critical - no HTML tags or wrappers for XML files
- document.write(content);
- } else {
- // For robots.txt, use the pre tag to preserve formatting
- document.write(`${content}`);
- }
-
- document.close();
-
- // Set the correct content type meta tag
- const meta = document.createElement('meta');
- meta.httpEquiv = 'Content-Type';
- meta.content = `${contentType}; charset=utf-8`;
- document.head.appendChild(meta);
-
- // Add minimal styling for robots.txt only
- if (!contentType.includes('xml')) {
- const style = document.createElement('style');
- style.textContent = `
- pre {
- font-family: monospace;
- font-size: 14px;
- line-height: 1.5;
- margin: 0;
- padding: 15px;
- }
- `;
- document.head.appendChild(style);
- }
- }
- }, [content, contentType]);
-
- // If there was an error, show a simple error message
- if (error) {
- return {error}
;
- }
-
- // During loading, return nothing (blank page)
- return null;
-};
-
-/**
- * Routes component that handles SEO file requests
- */
-const SeoProxyRoutes = () => {
- return (
-
- } />
- } />
-
- );
-};
-
-export default SeoProxyRoutes;
\ No newline at end of file
diff --git a/frontend/src/services/seoapi.js b/frontend/src/services/seoapi.js
deleted file mode 100644
index 1620c2e..0000000
--- a/frontend/src/services/seoapi.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import axios from 'axios';
-import { store } from '../store';
-
-let url = "";
-if(import.meta.env.VITE_ENVIRONMENT === "beta"){
- url = import.meta.env.VITE_API_URL.split('/api')[0]
-}else {
- url = `https://${import.meta.env.VITE_API_PROD_URL}`
-}
-
-const axiosClient = axios.create({
- baseURL: url,
- headers: {
- 'Content-Type': 'application/json',
- },
-});
-// console.log(url, `https://${import.meta.env.VITE_API_PROD_URL}`)
-axiosClient.interceptors.request.use(
- (config) => {
- const state = store.getState();
- const apiKey = state.auth.apiKey;
-
- if (apiKey) {
- config.headers['X-API-Key'] = apiKey;
- }
-
- return config;
- },
- (error) => {
- return Promise.reject(error);
- }
-);
-
-// Add response interceptor to handle common errors
-axiosClient.interceptors.response.use(
- (response) => response,
- (error) => {
- // Handle 401 unauthorized errors
- if (error.response && error.response.status === 401) {
- console.log("Missing Seo Files")
- }
-
- return Promise.reject(error);
- }
-);
-
-export default axiosClient;
\ No newline at end of file