diff --git a/src/components/seo/JsonLd.tsx b/src/components/seo/JsonLd.tsx
index 0077eba..60ab37a 100644
--- a/src/components/seo/JsonLd.tsx
+++ b/src/components/seo/JsonLd.tsx
@@ -25,7 +25,12 @@ export function PersonJsonLd({ locale }: JsonLdProps) {
? 'Razvoj AI agenata i rešenja za automatizaciju. Od voice AI platformi do autonomnih web agenata.'
: 'Remote AI developer building AI agents and automation solutions for clients in USA, UK and Europe. From voice AI platforms to autonomous web agents.',
url: baseUrl,
- image: `${baseUrl}/images/og-image.jpg`,
+ image: {
+ '@type': 'ImageObject',
+ url: `${baseUrl}/images/og-image.jpg`,
+ width: 1200,
+ height: 630,
+ },
email: 'info@damjan-savic.com',
telephone: '+491756950979',
address: {
@@ -34,6 +39,33 @@ export function PersonJsonLd({ locale }: JsonLdProps) {
addressRegion: 'NRW',
addressCountry: 'DE',
},
+ // Languages known
+ knowsLanguage: [
+ { '@type': 'Language', name: 'German', alternateName: 'de' },
+ { '@type': 'Language', name: 'English', alternateName: 'en' },
+ { '@type': 'Language', name: 'Serbian', alternateName: 'sr' },
+ ],
+ // Current occupation
+ hasOccupation: {
+ '@type': 'Occupation',
+ name: locale === 'de' ? 'Freelance KI-Entwickler' : locale === 'sr' ? 'Freelance AI Developer' : 'Freelance AI Developer',
+ occupationLocation: {
+ '@type': 'City',
+ name: locale === 'sr' ? 'Keln' : locale === 'en' ? 'Cologne' : 'Köln',
+ },
+ skills: [
+ 'AI Development',
+ 'Process Automation',
+ 'Voice AI',
+ 'n8n Workflows',
+ 'SaaS Development',
+ 'Full-Stack Development',
+ ],
+ },
+ // Works for self (freelancer)
+ worksFor: {
+ '@id': `${baseUrl}/#business`,
+ },
sameAs: [
'https://www.linkedin.com/in/damjansavic/',
'https://github.com/damjansavic',
@@ -50,6 +82,9 @@ export function PersonJsonLd({ locale }: JsonLdProps) {
'Next.js',
'n8n',
'SaaS Development',
+ 'Claude AI',
+ 'GPT-4',
+ 'LangChain',
],
alumniOf: [
{
@@ -69,6 +104,11 @@ export function PersonJsonLd({ locale }: JsonLdProps) {
credentialCategory: 'degree',
},
],
+ // Nationality for geo-targeting
+ nationality: {
+ '@type': 'Country',
+ name: 'Germany',
+ },
};
return (
@@ -719,7 +759,7 @@ export function SoftwareAppJsonLd({
);
}
-// WebSite Schema for Search Box
+// WebSite Schema for Search Box with SearchAction
export function WebSiteJsonLd({ locale }: JsonLdProps) {
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://damjan-savic.com';
@@ -747,6 +787,197 @@ export function WebSiteJsonLd({ locale }: JsonLdProps) {
{ '@type': 'Language', name: 'English', alternateName: 'en' },
{ '@type': 'Language', name: 'Serbian', alternateName: 'sr' },
],
+ // Potential site search action (for future implementation)
+ potentialAction: {
+ '@type': 'SearchAction',
+ target: {
+ '@type': 'EntryPoint',
+ urlTemplate: `${baseUrl}/${locale}/portfolio?search={search_term_string}`,
+ },
+ 'query-input': 'required name=search_term_string',
+ },
+ };
+
+ return (
+
+ );
+}
+
+// ContactPage Schema for Contact Page
+export function ContactPageJsonLd({ locale }: JsonLdProps) {
+ const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://damjan-savic.com';
+
+ const schema = {
+ '@context': 'https://schema.org',
+ '@type': 'ContactPage',
+ '@id': `${baseUrl}/${locale}/contact/#webpage`,
+ name: locale === 'de'
+ ? 'Kontakt - Damjan Savić'
+ : locale === 'sr'
+ ? 'Kontakt - Damjan Savić'
+ : 'Contact - Damjan Savić',
+ description: locale === 'de'
+ ? 'Kontaktieren Sie Damjan Savić für KI-Entwicklung, Prozessautomatisierung und SaaS-Projekte.'
+ : locale === 'sr'
+ ? 'Kontaktirajte Damjana Savića za AI razvoj, automatizaciju procesa i SaaS projekte.'
+ : 'Contact Damjan Savić for AI development, process automation, and SaaS projects.',
+ url: `${baseUrl}/${locale}/contact`,
+ inLanguage: locale === 'de' ? 'de-DE' : locale === 'sr' ? 'sr-RS' : 'en-US',
+ isPartOf: {
+ '@id': `${baseUrl}/#website`,
+ },
+ about: {
+ '@id': `${baseUrl}/#person`,
+ },
+ mainEntity: {
+ '@type': 'ContactPoint',
+ contactType: locale === 'de' ? 'Kundenservice' : locale === 'sr' ? 'Korisnička podrška' : 'customer service',
+ email: 'info@damjan-savic.com',
+ telephone: '+491756950979',
+ availableLanguage: [
+ { '@type': 'Language', name: 'German' },
+ { '@type': 'Language', name: 'English' },
+ { '@type': 'Language', name: 'Serbian' },
+ ],
+ areaServed: [
+ { '@type': 'Country', name: 'Germany' },
+ { '@type': 'Country', name: 'United States' },
+ { '@type': 'Country', name: 'United Kingdom' },
+ { '@type': 'Country', name: 'Austria' },
+ { '@type': 'Country', name: 'Switzerland' },
+ { '@type': 'Country', name: 'Serbia' },
+ ],
+ },
+ };
+
+ return (
+
+ );
+}
+
+// CollectionPage Schema for Portfolio with ItemList
+interface PortfolioProject {
+ name: string;
+ description: string;
+ url: string;
+ image?: string;
+ dateCreated?: string;
+ technologies?: string[];
+}
+
+export function CollectionPageJsonLd({
+ locale,
+ projects,
+}: {
+ locale: Locale;
+ projects: PortfolioProject[];
+}) {
+ const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://damjan-savic.com';
+
+ const schema = {
+ '@context': 'https://schema.org',
+ '@type': 'CollectionPage',
+ '@id': `${baseUrl}/${locale}/portfolio/#webpage`,
+ name: locale === 'de'
+ ? 'Portfolio - Damjan Savić'
+ : locale === 'sr'
+ ? 'Portfolio - Damjan Savić'
+ : 'Portfolio - Damjan Savić',
+ description: locale === 'de'
+ ? 'Ausgewählte KI- und Automatisierungsprojekte von Damjan Savić. Von Voice AI bis n8n-Workflows.'
+ : locale === 'sr'
+ ? 'Odabrani AI i automatizacija projekti Damjana Savića. Od Voice AI do n8n workflow-ova.'
+ : 'Selected AI and automation projects by Damjan Savić. From Voice AI to n8n workflows.',
+ url: `${baseUrl}/${locale}/portfolio`,
+ inLanguage: locale === 'de' ? 'de-DE' : locale === 'sr' ? 'sr-RS' : 'en-US',
+ isPartOf: {
+ '@id': `${baseUrl}/#website`,
+ },
+ author: {
+ '@id': `${baseUrl}/#person`,
+ },
+ mainEntity: {
+ '@type': 'ItemList',
+ itemListElement: projects.map((project, index) => ({
+ '@type': 'ListItem',
+ position: index + 1,
+ item: {
+ '@type': 'CreativeWork',
+ name: project.name,
+ description: project.description,
+ url: project.url.startsWith('http') ? project.url : `${baseUrl}${project.url}`,
+ ...(project.image && {
+ image: project.image.startsWith('http') ? project.image : `${baseUrl}${project.image}`,
+ }),
+ ...(project.dateCreated && { dateCreated: project.dateCreated }),
+ ...(project.technologies && {
+ keywords: project.technologies.join(', '),
+ }),
+ author: {
+ '@id': `${baseUrl}/#person`,
+ },
+ },
+ })),
+ numberOfItems: projects.length,
+ },
+ };
+
+ return (
+
+ );
+}
+
+// Generic ItemList Schema for any list of items
+interface ItemListItem {
+ name: string;
+ description?: string;
+ url?: string;
+ image?: string;
+}
+
+export function ItemListJsonLd({
+ name,
+ description,
+ items,
+ itemType = 'ListItem',
+ locale,
+}: {
+ name: string;
+ description?: string;
+ items: ItemListItem[];
+ itemType?: string;
+ locale: Locale;
+}) {
+ const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://damjan-savic.com';
+
+ const schema = {
+ '@context': 'https://schema.org',
+ '@type': 'ItemList',
+ name: name,
+ ...(description && { description }),
+ inLanguage: locale === 'de' ? 'de-DE' : locale === 'sr' ? 'sr-RS' : 'en-US',
+ itemListElement: items.map((item, index) => ({
+ '@type': itemType,
+ position: index + 1,
+ name: item.name,
+ ...(item.description && { description: item.description }),
+ ...(item.url && {
+ url: item.url.startsWith('http') ? item.url : `${baseUrl}${item.url}`,
+ }),
+ ...(item.image && {
+ image: item.image.startsWith('http') ? item.image : `${baseUrl}${item.image}`,
+ }),
+ })),
+ numberOfItems: items.length,
};
return (
diff --git a/src/components/seo/index.ts b/src/components/seo/index.ts
index ef4bc7f..de6bb1c 100644
--- a/src/components/seo/index.ts
+++ b/src/components/seo/index.ts
@@ -12,4 +12,7 @@ export {
ProfilePageJsonLd,
VideoJsonLd,
SoftwareAppJsonLd,
+ ContactPageJsonLd,
+ CollectionPageJsonLd,
+ ItemListJsonLd,
} from './JsonLd';