fix: resolve API URL duplication, CORS issues, and image localhost URLs

- Fix duplicate /api/v1 in analytics.ts API calls
- Add STRAPI_PUBLIC_URL env var for public CMS access
- Update strapi.service to use public URL for images instead of localhost
- Images now use https://cms.placebo.mk instead of http://localhost:1337
This commit is contained in:
echo 2026-02-28 23:29:54 +01:00
parent ebd1fc28d5
commit a66db56156
3 changed files with 15 additions and 14 deletions

View File

@ -87,6 +87,7 @@ interface StrapiResponse<T> {
export class StrapiService {
private readonly logger = new Logger(StrapiService.name);
private readonly strapiUrl: string;
private readonly strapiPublicUrl: string;
private readonly strapiApiToken: string;
constructor(
@ -101,6 +102,9 @@ export class StrapiService {
) {
this.strapiUrl =
this.configService.get<string>('STRAPI_URL') || 'http://localhost:1337';
this.strapiPublicUrl =
this.configService.get<string>('STRAPI_PUBLIC_URL') ||
this.strapiUrl.replace('cms:', 'localhost:');
this.strapiApiToken =
this.configService.get<string>('STRAPI_API_TOKEN') || '';
}
@ -182,10 +186,8 @@ export class StrapiService {
// If URL is relative, prepend Strapi base URL
if (imageUrl.startsWith('/')) {
// Convert Docker service URL to localhost for frontend access
// Backend uses http://cms:1337 internally, but frontend needs http://localhost:1337
const frontendStrapiUrl = this.strapiUrl.replace('cms:', 'localhost:');
return `${frontendStrapiUrl}${imageUrl}`;
// Use public URL for frontend access
return `${this.strapiPublicUrl}${imageUrl}`;
}
return imageUrl;
@ -210,10 +212,8 @@ export class StrapiService {
// If URL is relative, prepend Strapi base URL
if (imageUrl.startsWith('/')) {
// Convert Docker service URL to localhost for frontend access
// Backend uses http://cms:1337 internally, but frontend needs http://localhost:1337
const frontendStrapiUrl = this.strapiUrl.replace('cms:', 'localhost:');
return `${frontendStrapiUrl}${imageUrl}`;
// Use public URL for frontend access
return `${this.strapiPublicUrl}${imageUrl}`;
}
return imageUrl;

View File

@ -80,6 +80,7 @@ services:
FRONTEND_URL: https://placebo.mk
PWA_URL: https://app.placebo.mk
STRAPI_URL: http://cms:1337
STRAPI_PUBLIC_URL: https://cms.placebo.mk
VAPID_SUBJECT: ${VAPID_SUBJECT:-mailto:contact@placebo.mk}
VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY}
VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY}

View File

@ -1,6 +1,6 @@
import { type SharePlatform } from './social-utils';
const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:3000';
const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:3000/api/v1';
export interface TrackShareParams {
articleId: string;
@ -11,7 +11,7 @@ export interface TrackShareParams {
export const trackShare = async (params: TrackShareParams): Promise<boolean> => {
try {
const response = await fetch(`${API_BASE_URL}/api/v1/analytics/share`, {
const response = await fetch(`${API_BASE_URL}/analytics/share`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@ -34,8 +34,8 @@ export const trackShare = async (params: TrackShareParams): Promise<boolean> =>
export const getShareStats = async (articleId?: string) => {
try {
const url = articleId
? `${API_BASE_URL}/api/v1/analytics/shares?articleId=${articleId}`
: `${API_BASE_URL}/api/v1/analytics/shares`;
? `${API_BASE_URL}/analytics/shares?articleId=${articleId}`
: `${API_BASE_URL}/analytics/shares`;
const response = await fetch(url, {
headers: {
@ -57,7 +57,7 @@ export const getShareStats = async (articleId?: string) => {
export const getTopSharedArticles = async (limit: number = 10) => {
try {
const response = await fetch(`${API_BASE_URL}/api/v1/analytics/shares/top?limit=${limit}`, {
const response = await fetch(`${API_BASE_URL}/analytics/shares/top?limit=${limit}`, {
headers: {
'Content-Type': 'application/json',
},
@ -77,7 +77,7 @@ export const getTopSharedArticles = async (limit: number = 10) => {
export const getTotalShareStats = async () => {
try {
const response = await fetch(`${API_BASE_URL}/api/v1/analytics/shares/total`, {
const response = await fetch(`${API_BASE_URL}/analytics/shares/total`, {
headers: {
'Content-Type': 'application/json',
},