From 77df5d6cd872e61f44be92d44398d94f20a21f61 Mon Sep 17 00:00:00 2001 From: 2ManyProjects Date: Wed, 7 May 2025 22:37:15 -0500 Subject: [PATCH] properly shared seo fiels between containers --- backend/src/services/sitemapService.js | 2 +- docker-compose.yml | 5 +- frontend/src/App.jsx | 4 - frontend/src/components/SeoProxyRoutes.jsx | 96 ---------------------- frontend/src/services/seoapi.js | 47 ----------- 5 files changed, 5 insertions(+), 149 deletions(-) delete mode 100644 frontend/src/components/SeoProxyRoutes.jsx delete mode 100644 frontend/src/services/seoapi.js 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