Files
portifolio-evandrodevbr/app/layout.tsx
T
Evandro Fonseca Junior ad6a76efdd feat(config, layout, components): enhance security headers, improve SEO, and update project descriptions
- Added security headers in the Next.js configuration to enhance application security.
- Updated metadata in the layout component for improved SEO, including new titles, descriptions, and keywords.
- Introduced JSON-LD schema for projects to enhance search engine visibility.
- Enhanced project descriptions in the portfolio data for clarity and detail.
- Improved header component with logo integration and refined social media links for better accessibility.
2026-01-20 21:00:50 -03:00

247 lines
8.0 KiB
TypeScript

import type { Metadata, Viewport } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import Script from "next/script";
// Importação necessária para corrigir o erro de namespace e tipagem do children
import { ReactNode } from "react";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
display: "swap",
adjustFontFallback: true,
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
display: "swap",
adjustFontFallback: true,
});
export const metadata: Metadata = {
title: "Evandro Fonseca Junior - Engenheiro Full-Stack | Next.js, React, Tauri Specialist",
description:
"Engenheiro Full-Stack especializado em Next.js, React, Angular, Node.js e Tauri. Desenvolvedor de sistemas web escaláveis, aplicações desktop e automação. Experiência em PostgreSQL, MySQL, computação em nuvem e IoT.",
keywords: [
"engenheiro full-stack",
"Next.js specialist",
"React developer",
"Tauri developer",
"Angular",
"Node.js",
"TypeScript",
"PostgreSQL",
"MySQL",
"computação em nuvem",
"IoT",
"automação",
"arquitetura de software",
"sistemas escaláveis",
],
authors: [{ name: "Evandro Fonseca Junior" }],
creator: "Evandro Fonseca Junior",
publisher: "Evandro Fonseca Junior",
formatDetection: {
email: false,
address: false,
telephone: false,
},
metadataBase: new URL("https://evandro.dev.br"),
alternates: {
canonical: "/",
},
openGraph: {
title: "Evandro Fonseca Junior - Engenheiro Full-Stack | Next.js, React, Tauri Specialist",
description:
"Engenheiro Full-Stack especializado em Next.js, React, Angular, Node.js e Tauri. Desenvolvedor de sistemas web escaláveis e aplicações desktop.",
url: "https://evandro.dev.br",
siteName: "Evandro Fonseca Junior",
locale: "pt_BR",
type: "website",
images: [
{
url: "/opengraph-image",
width: 1200,
height: 630,
alt: "Evandro Fonseca Junior - Engenheiro Full-Stack | Next.js, React, Tauri Specialist",
},
],
},
twitter: {
card: "summary_large_image",
title: "Evandro Fonseca Junior - Engenheiro Full-Stack | Next.js, React, Tauri Specialist",
description:
"Engenheiro Full-Stack especializado em Next.js, React, Angular, Node.js e Tauri. Desenvolvedor de sistemas web escaláveis e aplicações desktop.",
creator: "@evandrodevbr",
images: ["/opengraph-image"],
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
"max-video-preview": -1,
"max-image-preview": "large",
"max-snippet": -1,
},
},
};
export const viewport: Viewport = {
themeColor: "#000000",
width: "device-width",
initialScale: 1,
maximumScale: 5,
};
// Interface tipada corretamente
interface RootLayoutProps {
children: ReactNode;
}
export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
const jsonLd = {
"@context": "https://schema.org",
"@type": "ProfilePage",
"mainEntity": {
"@type": "Person",
"name": "Evandro Fonseca Junior",
"alternateName": "Evandro.dev",
"jobTitle": "Engenheiro de Software Full-Stack",
"url": "https://evandro.dev.br",
"sameAs": [
"https://github.com/evandrodevbr",
"https://www.linkedin.com/in/evandro-fonseca-junior-0969aa1b0/",
],
"knowsAbout": [
"Software Engineering",
"Next.js",
"React",
"Angular",
"Node.js",
"TypeScript",
"Tauri",
"System Architecture",
"Cloud Computing",
"IoT",
"Automation",
"PostgreSQL",
"MySQL",
],
"worksFor": {
"@type": "Organization",
"name": "Freelancer / Consultor Independente",
},
"description":
"Engenheiro de software especializado em arquitetura web moderna, automação e sistemas de alta performance. Experiência em Next.js, React, Angular, Node.js e desenvolvimento de aplicações desktop com Tauri.",
},
};
return (
<html lang="pt-BR">
<head>
{/* Preconnect to external origins for better performance */}
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossOrigin="anonymous"
/>
<link rel="preconnect" href="https://wa.me" />
<link rel="preconnect" href="https://www.linkedin.com" />
<link rel="preconnect" href="https://github.com" />
{/* DNS prefetch for additional performance */}
<link rel="dns-prefetch" href="//fonts.googleapis.com" />
<link rel="dns-prefetch" href="//fonts.gstatic.com" />
<link rel="dns-prefetch" href="//wa.me" />
<link rel="dns-prefetch" href="//www.linkedin.com" />
<link rel="dns-prefetch" href="//github.com" />
{/* SEO and Crawling */}
<link rel="canonical" href="https://evandro.dev.br" />
{/* Theme color for mobile browsers */}
<meta name="msapplication-TileColor" content="#000000" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>
<meta name="apple-mobile-web-app-title" content="Evandro.dev" />
{/* Performance hints */}
<link rel="preload" href="/edev.jpeg" as="image" />
</head>
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
{children}
<Script
src="/analytics/api/script.js"
data-site-id="1"
data-debounce="100"
data-replay-mask-text-selectors='["#user-name", "#user-email", "#user-phone", "input[type=email]", "input[type=tel]", "textarea"]'
data-replay-block-class="rr-block"
data-replay-ignore-class="rr-ignore"
strategy="afterInteractive"
data-session-replay="true"
data-track-errors="true"
/>
{/* Google Analytics - Interceptor para bypass de adblocker */}
<Script
id="google-analytics-proxy-interceptor"
strategy="beforeInteractive"
dangerouslySetInnerHTML={{
__html: `
(function() {
// Interceptar fetch
const originalFetch = window.fetch;
window.fetch = function(url, options) {
if (typeof url === 'string' && url.includes('google-analytics.com')) {
url = url.replace('https://www.google-analytics.com', '/ga');
}
return originalFetch.call(this, url, options);
};
// Interceptar XMLHttpRequest
const originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
if (typeof url === 'string' && url.includes('google-analytics.com')) {
url = url.replace('https://www.google-analytics.com', '/ga');
}
return originalOpen.call(this, method, url, ...rest);
};
})();
`,
}}
/>
{/* Google Analytics - Script principal via proxy */}
<Script
src="/gtm/js/G-QTT9QT0T3S"
strategy="afterInteractive"
async
/>
{/* Google Analytics - Inicialização */}
<Script
id="google-analytics-init"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-QTT9QT0T3S');
`,
}}
/>
</body>
</html>
);
}