{"id":38480,"date":"2026-02-01T07:30:38","date_gmt":"2026-02-01T04:30:38","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/"},"modified":"2026-02-01T07:30:38","modified_gmt":"2026-02-01T04:30:38","slug":"next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/","title":{"rendered":"Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run&#8217;a Da\u011f\u0131tma"},"content":{"rendered":"<h2>Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run&#8217;a Da\u011f\u0131tma<\/h2>\n<p>G\u00fcn\u00fcm\u00fcz dijital d\u00fcnyas\u0131nda, projelerinizi ve deneyimlerinizi sergilemenin yarat\u0131c\u0131 yollar\u0131n\u0131 bulmak b\u00fcy\u00fck \u00f6nem ta\u015f\u0131r. Geleneksel \u00f6zge\u00e7mi\u015fler veya statik portf\u00f6y siteleri yerine, interaktif bir portf\u00f6y haritas\u0131, \u00e7al\u0131\u015fmalar\u0131n\u0131z\u0131 co\u011frafi ba\u011flamda sunarak ziyaret\u00e7ilerinize benzersiz ve ak\u0131lda kal\u0131c\u0131 bir deneyim sunabilir. Bu makalede, modern web geli\u015ftirme teknolojileri olan Next.js ile b\u00f6yle bir haritay\u0131 nas\u0131l olu\u015fturaca\u011f\u0131n\u0131z\u0131 ve Google Cloud Run&#8217;\u0131n sunucusuz mimarisi \u00fczerinde nas\u0131l g\u00fcvenilir ve \u00f6l\u00e7eklenebilir bir \u015fekilde da\u011f\u0131taca\u011f\u0131n\u0131z\u0131 ad\u0131m ad\u0131m inceleyece\u011fiz.<\/p>\n<h3>Giri\u015f: Neden \u0130nteraktif Bir Portf\u00f6y Haritas\u0131?<\/h3>\n<p>Kariyeriniz boyunca farkl\u0131 \u015fehirlerde veya \u00fclkelerde ger\u00e7ekle\u015ftirdi\u011finiz projeleri, kat\u0131ld\u0131\u011f\u0131n\u0131z etkinlikleri veya edindi\u011finiz deneyimleri g\u00f6rsel ve etkile\u015fimli bir harita \u00fczerinde sergilemek, potansiyel i\u015fverenlere, m\u00fc\u015fterilere veya i\u015fbirlik\u00e7ilere kendinizi \u00e7ok daha etkili bir \u015fekilde tan\u0131tman\u0131z\u0131 sa\u011flar. Bu yakla\u015f\u0131m, sadece teknik becerilerinizi de\u011fil, ayn\u0131 zamanda yarat\u0131c\u0131l\u0131\u011f\u0131n\u0131z\u0131 ve hikaye anlatma yetene\u011finizi de ortaya koyar.<\/p>\n<h4>Geleneksel Portf\u00f6ylerin S\u0131n\u0131rlar\u0131<\/h4>\n<p>Geleneksel portf\u00f6yler genellikle kronolojik listeler veya statik proje sayfalar\u0131ndan olu\u015fur. Bu yap\u0131lar, i\u00e7eri\u011fi d\u00fczenli bir \u015fekilde sunsa da, projeler aras\u0131ndaki co\u011frafi ba\u011flant\u0131lar\u0131 veya global deneyimleri g\u00f6rselle\u015ftirmede yetersiz kal\u0131r. Okuyucunun dikkatini \u00e7ekmek ve ak\u0131lda kal\u0131c\u0131 bir izlenim b\u0131rakmak genellikle zordur.<\/p>\n<h4>\u0130nteraktif Haritan\u0131n Avantajlar\u0131<\/h4>\n<p>\u0130nteraktif bir portf\u00f6y haritas\u0131, projelerinizi d\u00fcnya haritas\u0131 \u00fczerinde i\u015faretleyerek ziyaret\u00e7ilere ke\u015ffedilebilir bir deneyim sunar. Kullan\u0131c\u0131lar, ilgilendikleri b\u00f6lgelere yak\u0131nla\u015fabilir, i\u015faret\u00e7ilere t\u0131klayarak projelerin detaylar\u0131na ula\u015fabilir ve sizin global ayak izinizin bir par\u00e7as\u0131 olabilirler. Bu, hem g\u00f6rsel a\u00e7\u0131dan zengin hem de kullan\u0131c\u0131 deneyimi a\u00e7\u0131s\u0131ndan tatmin edici bir yakla\u015f\u0131md\u0131r.<\/p>\n<h4>Teknolojik Se\u00e7imlerimiz: Next.js ve Harita K\u00fct\u00fcphaneleri<\/h4>\n<p>Bu projede, React tabanl\u0131, sunucu taraf\u0131 render (SSR) ve statik site olu\u015fturma (SSG) yetenekleriyle \u00f6ne \u00e7\u0131kan Next.js framework&#8217;\u00fcn\u00fc kullanaca\u011f\u0131z. Next.js, performans, SEO ve geli\u015ftirici deneyimi a\u00e7\u0131s\u0131ndan modern web uygulamalar\u0131 i\u00e7in ideal bir se\u00e7imdir. Harita entegrasyonu i\u00e7in ise React ekosistemiyle uyumlu, pop\u00fcler bir harita k\u00fct\u00fcphanesi olan React-Leaflet&#8217;i tercih edece\u011fiz. Da\u011f\u0131t\u0131m i\u00e7in ise sunucusuz mimarisiyle \u00f6ne \u00e7\u0131kan, maliyet etkin ve kolay y\u00f6netilebilir Google Cloud Run&#8217;\u0131 kullanaca\u011f\u0131z.<\/p>\n<h3>Next.js ile Proje Kurulumu ve Temel Yap\u0131land\u0131rma<\/h3>\n<p>Projemize ba\u015flamadan \u00f6nce, gerekli ara\u00e7lar\u0131n (Node.js ve npm\/yarn) sisteminizde kurulu oldu\u011fundan emin olun. Ard\u0131ndan, Next.js uygulamas\u0131n\u0131 olu\u015fturmak i\u00e7in terminalimizi kullanaca\u011f\u0131z.<\/p>\n<h4>Yeni Bir Next.js Uygulamas\u0131 Ba\u015flatma<\/h4>\n<p>Yeni bir Next.js projesi olu\u015fturmak i\u00e7in a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code class=\"language-bash\">npx create-next-app my-portfolio-map --ts\ncd my-portfolio-map\n<\/pre>\n<p><\/code><\/p>\n<p>Bu komut, TypeScript destekli yeni bir Next.js projesi olu\u015fturacak ve gerekli ba\u011f\u0131ml\u0131l\u0131klar\u0131 kuracakt\u0131r.<\/p>\n<h4>Gerekli Ba\u011f\u0131ml\u0131l\u0131klar\u0131 Kurma<\/h4>\n<p>\u0130nteraktif harita i\u00e7in React-Leaflet ve Leaflet k\u00fct\u00fcphanelerini kurmam\u0131z gerekiyor. Leaflet, harita motorunu sa\u011flarken, React-Leaflet bu motoru React bile\u015fenleri arac\u0131l\u0131\u011f\u0131yla kullanmam\u0131z\u0131 sa\u011flar.<\/p>\n<pre><code class=\"language-bash\">npm install leaflet react-leaflet\nnpm install --save-dev @types\/leaflet\n<\/pre>\n<p><\/code><\/p>\n<p>Ayr\u0131ca, Leaflet'in stil dosyalar\u0131n\u0131 da projemize dahil etmemiz gerekecek. Bunu genellikle <code>_app.tsx<\/code> dosyas\u0131nda veya harita bile\u015feninin kendisinde yapabiliriz.<\/p>\n<h4>Proje Klas\u00f6r Yap\u0131s\u0131 ve Temel Bile\u015fenler<\/h4>\n<p>Next.js'in tipik klas\u00f6r yap\u0131s\u0131 \u015f\u00f6yledir:<\/p>\n<ul>\n<li><code>pages\/<\/code>: Uygulaman\u0131z\u0131n rotalar\u0131n\u0131 tan\u0131mlayan React bile\u015fenleri.<\/li>\n<li><code>components\/<\/code>: Tekrar kullan\u0131labilir UI bile\u015fenleri.<\/li>\n<li><code>public\/<\/code>: Statik dosyalar (resimler, fontlar vb.).<\/li>\n<li><code>styles\/<\/code>: Global veya mod\u00fcl bazl\u0131 CSS dosyalar\u0131.<\/li>\n<\/ul>\n<p>Harita bile\u015fenimiz i\u00e7in <code>components\/Map.tsx<\/code> gibi bir dosya olu\u015fturaca\u011f\u0131z. Portf\u00f6y verilerimizi ise <code>data\/portfolio-data.json<\/code> gibi bir dosyada tutabiliriz.<\/p>\n<h3>\u0130nteraktif Harita Bile\u015fenini Olu\u015fturma<\/h3>\n<p>\u015eimdi projemizin kalbi olan harita bile\u015fenini olu\u015fturmaya ge\u00e7elim. Next.js'te harita k\u00fct\u00fcphaneleri genellikle istemci taraf\u0131nda (client-side) render edilmesi gerekti\u011fi i\u00e7in dinamik import kullanmak \u00f6nemlidir.<\/p>\n<h4>Harita K\u00fct\u00fcphanesini Entegre Etme (React-Leaflet)<\/h4>\n<p><code>components\/Map.tsx<\/code> dosyas\u0131nda temel bir harita bile\u015feni olu\u015ftural\u0131m. Leaflet'in CSS dosyas\u0131n\u0131 da import etmeyi unutmay\u0131n.<\/p>\n<pre><code class=\"language-tsx\">\/\/ components\/Map.tsx\nimport { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';\nimport 'leaflet\/dist\/leaflet.css';\nimport L from 'leaflet'; \/\/ Leaflet'in varsay\u0131lan ikonlar\u0131n\u0131 d\u00fczeltmek i\u00e7in\n\n\/\/ Leaflet'in varsay\u0131lan ikonlar\u0131n\u0131n bozuk g\u00f6r\u00fcnmesini engellemek i\u00e7in ge\u00e7ici \u00e7\u00f6z\u00fcm\ndelete L.Icon.Default.prototype._get='https:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/e\/e0\/Google_Cloud_Run_logo.svg\/1200px-Google_Cloud_Run_logo.svg.png';\nL.Icon.Default.mergeOptions({\n  iconRetinaUrl: 'leaflet\/images\/marker-icon-2x.png',\n  iconUrl: 'leaflet\/images\/marker-icon.png',\n  shadowUrl: 'leaflet\/images\/marker-shadow.png',\n});\n\ninterface PortfolioItem {\n  id: string;\n  name: string;\n  description: string;\n  position: [number, number]; \/\/ [latitude, longitude]\n  link?: string;\n}\n\ninterface MapProps {\n  items: PortfolioItem[];\n}\n\nconst Map = ({ items }: MapProps) => {\n  const defaultPosition: [number, number] = [39.9334, 32.8597]; \/\/ Ankara\n  const defaultZoom = 6;\n\n  return (\n    <MapContainer center={defaultPosition} zoom={defaultZoom} style={{ height: '100vh', width: '100%' }}>\n      <TileLayer\n        attribution='\u00a9 <a href=\"https:\/\/www.openstreetmap.org\/copyright\">OpenStreetMap<\/a> contributors'\n        url=\"https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png\"\n      \/>\n      {items.map(item => (\n        <Marker key={item.id} position={item.position}>\n          <Popup>\n            <h3>{item.name}<\/h3>\n            <p>{item.description}<\/p>\n            {item.link && <a href={item.link} target=\"_blank\" rel=\"noopener noreferrer\">Detaylar\u0131 G\u00f6r<\/a>}\n          <\/Popup>\n        <\/Marker>\n      ))}\n    <\/MapContainer>\n  );\n};\n\nexport default Map;\n<\/pre>\n<p><\/code><\/p>\n<p>Bu bile\u015feni <code>pages\/index.tsx<\/code> dosyas\u0131nda dinamik olarak import etmeliyiz:<\/p>\n<pre><code class=\"language-tsx\">\/\/ pages\/index.tsx\nimport dynamic from 'next\/dynamic';\nimport Head from 'next\/head';\nimport { useState, useEffect } from 'react';\n\n\/\/ Dinamik import ile harita bile\u015fenini sadece istemci taraf\u0131nda render et\nconst DynamicMap = dynamic(() => import('..\/components\/Map'), {\n  ssr: false, \/\/ Sunucu taraf\u0131nda render etme\n});\n\ninterface PortfolioItem {\n  id: string;\n  name: string;\n  description: string;\n  position: [number, number]; \/\/ [latitude, longitude]\n  link?: string;\n}\n\nconst Home = () => {\n  const [portfolioItems, setPortfolioItems] = useState<PortfolioItem[]>([]);\n\n  useEffect(() => {\n    \/\/ \u00d6rnek portf\u00f6y verileri (ger\u00e7ek uygulamada bir API'den gelebilir)\n    const data: PortfolioItem[] = [\n      { id: '1', name: 'Proje A', description: 'Web sitesi geli\u015ftirme.', position: [41.0082, 28.9784], link: 'https:\/\/example.com\/proje-a' }, \/\/ \u0130stanbul\n      { id: '2', name: 'Proje B', description: 'Mobil uygulama tasar\u0131m\u0131.', position: [38.4237, 27.1428], link: 'https:\/\/example.com\/proje-b' }, \/\/ \u0130zmir\n      { id: '3', name: 'Proje C', description: 'Veri analizi \u00e7al\u0131\u015fmas\u0131.', position: [36.8969, 30.7133] }, \/\/ Antalya\n    ];\n    setPortfolioItems(data);\n  }, []);\n\n  return (\n    <div>\n      <Head>\n        <title>Portf\u00f6y Haritam<\/title>\n        <meta name=\"description\" content=\"\u0130nteraktif portf\u00f6y haritam\u0131 ke\u015ffedin.\" \/>\n        <link rel=\"icon\" href=\"\/favicon.ico\" \/>\n      <\/Head>\n\n      <main style={{ height: '100vh', width: '100vw' }}>\n        <h1 style={{ display: 'none' }}>\u0130nteraktif Portf\u00f6y Haritas\u0131<\/h1>\n        <DynamicMap items={portfolioItems} \/>\n      <\/main>\n    <\/div>\n  );\n};\n\nexport default Home;\n<\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki kodda, <code>ssr: false<\/code> ayar\u0131 ile harita bile\u015feninin sadece taray\u0131c\u0131da \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011fl\u0131yoruz. Ayr\u0131ca, Leaflet'in varsay\u0131lan ikonlar\u0131n\u0131n Next.js ile do\u011fru y\u00fcklenmemesi sorununu gidermek i\u00e7in k\u00fc\u00e7\u00fck bir ge\u00e7ici \u00e7\u00f6z\u00fcm ekledik.<\/p>\n<h4>Harita Katmanlar\u0131 ve \u0130\u015faret\u00e7iler (Markers) Ekleme<\/h4>\n<p><code>TileLayer<\/code> bile\u015feni, haritan\u0131n arka plan\u0131n\u0131 olu\u015fturan d\u00f6\u015feme katmanlar\u0131n\u0131 tan\u0131mlar. OpenStreetMap'in \u00fccretsiz d\u00f6\u015feme sunucusunu kulland\u0131k. <code>Marker<\/code> bile\u015feni ise harita \u00fczerindeki belirli bir konumu i\u015faretler. Her i\u015faret\u00e7iye bir <code>Popup<\/code> ekleyerek, t\u0131kland\u0131\u011f\u0131nda projenin ad\u0131n\u0131, a\u00e7\u0131klamas\u0131n\u0131 ve iste\u011fe ba\u011fl\u0131 bir ba\u011flant\u0131y\u0131 g\u00f6sterebiliriz.<\/p>\n<h4>Harita \u00dczerinde Veri G\u00f6rselle\u015ftirme ve Etkile\u015fim<\/h4>\n<p><code>portfolioItems<\/code> dizisindeki her bir \u00f6\u011fe i\u00e7in bir <code>Marker<\/code> olu\u015fturarak, portf\u00f6y verilerimizi harita \u00fczerinde g\u00f6rselle\u015ftiriyoruz. Kullan\u0131c\u0131lar i\u015faret\u00e7ilere t\u0131klayarak ilgili projenin detaylar\u0131n\u0131 i\u00e7eren bir a\u00e7\u0131l\u0131r pencere (popup) g\u00f6rebilirler. Bu, portf\u00f6y\u00fcn\u00fczle interaktif bir deneyim sa\u011flar.<\/p>\n<h3>Portf\u00f6y Verilerini Y\u00f6netme ve G\u00f6r\u00fcnt\u00fcleme<\/h3>\n<p>Portf\u00f6y verilerinizin y\u00f6netimi, uygulaman\u0131z\u0131n esnekli\u011fi ve g\u00fcncellenebilirli\u011fi i\u00e7in kritik \u00f6neme sahiptir.<\/p>\n<h4>Veri Kayna\u011f\u0131 Se\u00e7imi (JSON, API, CMS)<\/h4>\n<p>K\u00fc\u00e7\u00fck bir portf\u00f6y i\u00e7in statik bir JSON dosyas\u0131 yeterli olabilir. Ancak, daha b\u00fcy\u00fck veya s\u0131k g\u00fcncellenen portf\u00f6yler i\u00e7in bir API veya headless CMS (Content Management System) kullanmak daha uygun olacakt\u0131r. \u00d6rnek kodumuzda basit bir JSON dizisi kulland\u0131k, ancak bu veri bir Next.js API rotas\u0131ndan veya harici bir servisten de \u00e7ekilebilir.<\/p>\n<pre><code class=\"language-json\">\/\/ data\/portfolio-data.json (\u00d6rnek)\n[\n  {\n    \"id\": \"1\",\n    \"name\": \"E-ticaret Platformu Geli\u015ftirme\",\n    \"description\": \"Kapsaml\u0131 bir e-ticaret \u00e7\u00f6z\u00fcm\u00fc i\u00e7in tam y\u0131\u011f\u0131n geli\u015ftirme.\",\n    \"position\": [41.0082, 28.9784],\n    \"link\": \"https:\/\/example.com\/ecommerce-project\"\n  },\n  {\n    \"id\": \"2\",\n    \"name\": \"Mobil Uygulama UI\/UX Tasar\u0131m\u0131\",\n    \"description\": \"Yenilik\u00e7i bir mobil uygulama i\u00e7in kullan\u0131c\u0131 aray\u00fcz\u00fc ve deneyim tasar\u0131m\u0131.\",\n    \"position\": [38.4237, 27.1428]\n  },\n  {\n    \"id\": \"3\",\n    \"name\": \"B\u00fcy\u00fck Veri Analizi Projesi\",\n    \"description\": \"Finans sekt\u00f6r\u00fcnde b\u00fcy\u00fck veri setlerinin analizi ve raporlama.\",\n    \"position\": [34.0522, -118.2437],\n    \"link\": \"https:\/\/example.com\/big-data-project\"\n  }\n]\n<\/pre>\n<p><\/code><\/p>\n<h4>Harita Verilerini Dinamik Olarak Y\u00fckleme<\/h4>\n<p>Verileri <code>useEffect<\/code> hook'u i\u00e7inde fetch edebilir ve <code>useState<\/code> ile y\u00f6netebiliriz. Ger\u00e7ek bir uygulamada, bu verileri <code>getStaticProps<\/code> veya <code>getServerSideProps<\/code> kullanarak Next.js'in veri getirme mekanizmalar\u0131yla sunucu taraf\u0131nda da \u00f6nceden y\u00fckleyebilirsiniz, ancak harita bile\u015feni istemci taraf\u0131nda render edildi\u011fi i\u00e7in, verinin de istemci taraf\u0131nda haz\u0131r olmas\u0131 yeterlidir.<\/p>\n<h4>\u0130\u015faret\u00e7i T\u0131klama Olaylar\u0131 ve Detay G\u00f6r\u00fcnt\u00fcleme<\/h4>\n<p><code>Popup<\/code> bile\u015feni, i\u015faret\u00e7iye t\u0131kland\u0131\u011f\u0131nda otomatik olarak a\u00e7\u0131l\u0131r. \u0130\u00e7ine HTML i\u00e7eri\u011fi yerle\u015ftirebilirsiniz. Daha karma\u015f\u0131k etkile\u015fimler i\u00e7in, <code>Marker<\/code> bile\u015fenine <code>onClick<\/code> olay dinleyicisi ekleyerek, t\u0131kland\u0131\u011f\u0131nda bir modal pencere a\u00e7abilir veya kullan\u0131c\u0131y\u0131 ba\u015fka bir detay sayfas\u0131na y\u00f6nlendirebilirsiniz.<\/p>\n<h3>Google Cloud Run'a Da\u011f\u0131t\u0131m \u0130\u00e7in Haz\u0131rl\u0131k<\/h3>\n<p>Uygulamam\u0131z\u0131 Next.js ile geli\u015ftirdik, \u015fimdi s\u0131ra onu d\u00fcnyaya a\u00e7maya geldi. Google Cloud Run, sunucusuz bir platform olup, konteynerle\u015ftirilmi\u015f uygulamalar\u0131 otomatik olarak \u00f6l\u00e7eklendirir ve y\u00f6netir. Bu, geli\u015ftiricilerin altyap\u0131 yerine kod yazmaya odaklanmas\u0131n\u0131 sa\u011flar.<\/p>\n<h4>Docker Nedir ve Neden Kullan\u0131l\u0131r?<\/h4>\n<p>Docker, uygulamalar\u0131 ve ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 izole edilmi\u015f bir ortamda, yani \"konteyner\" i\u00e7inde paketlemeye yarayan bir platformdur. Bu sayede uygulaman\u0131z\u0131n her ortamda (geli\u015ftirme, test, \u00fcretim) tutarl\u0131 bir \u015fekilde \u00e7al\u0131\u015fmas\u0131n\u0131 garanti edersiniz. Cloud Run, da\u011f\u0131t\u0131m i\u00e7in Docker konteynerlerini kullan\u0131r.<\/p>\n<h4>Dockerfile Olu\u015fturma (Next.js Uygulamas\u0131 \u0130\u00e7in)<\/h4>\n<p>Projenizin k\u00f6k dizininde <code>Dockerfile<\/code> ad\u0131nda bir dosya olu\u015fturun ve i\u00e7ine a\u015fa\u011f\u0131daki i\u00e7eri\u011fi ekleyin:<\/p>\n<pre><code class=\"language-docker\"># Temel imaj olarak Node.js 18 kullan\nFROM node:18-alpine AS builder\n\n# \u00c7al\u0131\u015fma dizinini ayarla\nWORKDIR \/app\n\n# Ba\u011f\u0131ml\u0131l\u0131klar\u0131 kopyala ve kur\nCOPY package.json yarn.lock .\/\nRUN yarn install --frozen-lockfile\n\n# Uygulama kaynak kodunu kopyala\nCOPY . .\n\n# Next.js uygulamas\u0131n\u0131 derle\nRUN yarn build\n\n# \u00dcretim imaj\u0131 i\u00e7in daha k\u00fc\u00e7\u00fck bir temel imaj kullan\nFROM node:18-alpine AS runner\n\nWORKDIR \/app\n\n# Next.js statik dosyalar\u0131n\u0131 ve build \u00e7\u0131kt\u0131s\u0131n\u0131 kopyala\nCOPY --from=builder \/app\/.next .\/.next\nCOPY --from=builder \/app\/node_modules .\/node_modules\nCOPY --from=builder \/app\/public .\/public\nCOPY --from=builder \/app\/package.json .\/package.json\n\n# Uygulaman\u0131n \u00e7al\u0131\u015faca\u011f\u0131 portu ayarla (Cloud Run i\u00e7in gerekli)\nENV PORT 8080\nEXPOSE 8080\n\n# Uygulamay\u0131 ba\u015flat\nCMD [\"yarn\", \"start\"]\n<\/pre>\n<p><\/code><\/p>\n<p>Bu <code>Dockerfile<\/code>, \u00e7ok a\u015famal\u0131 bir derleme (multi-stage build) kullan\u0131r. \u0130lk a\u015famada (<code>builder<\/code>), uygulaman\u0131n ba\u011f\u0131ml\u0131l\u0131klar\u0131 kurulur ve Next.js uygulamas\u0131 derlenir. \u0130kinci a\u015famada (<code>runner<\/code>), sadece uygulaman\u0131n \u00e7al\u0131\u015fmas\u0131 i\u00e7in gerekli olan dosyalar kopyalan\u0131r, bu da nihai Docker imaj\u0131n\u0131n boyutunu k\u00fc\u00e7\u00fclt\u00fcr. <code>PORT<\/code> ortam de\u011fi\u015fkeni Cloud Run i\u00e7in \u00f6nemlidir.<\/p>\n<h4>Google Cloud Projesi ve Gerekli API'leri Etkinle\u015ftirme<\/h4>\n<ol>\n<li>Google Cloud Console'a gidin ve yeni bir proje olu\u015fturun veya mevcut bir projeyi se\u00e7in.<\/li>\n<li>Projeniz i\u00e7in faturaland\u0131rmay\u0131 etkinle\u015ftirin (Cloud Run'\u0131n \u00fccretsiz katman\u0131 olsa da, faturaland\u0131rma hesab\u0131 gereklidir).<\/li>\n<li>\"Cloud Build API\" ve \"Cloud Run API\" hizmetlerini etkinle\u015ftirin. Bu API'ler, Docker imaj\u0131n\u0131z\u0131 olu\u015fturmak ve Cloud Run'a da\u011f\u0131tmak i\u00e7in gereklidir.<\/li>\n<\/ol>\n<h3>Google Cloud Run \u00dczerine Da\u011f\u0131t\u0131m<\/h3>\n<p>Uygulamam\u0131z\u0131n Docker imaj\u0131n\u0131 olu\u015fturup Google Container Registry'ye (GCR) y\u00fckledikten sonra, onu Cloud Run'a da\u011f\u0131tabiliriz.<\/p>\n<h4>Google Cloud SDK Kurulumu ve Kimlik Do\u011frulama<\/h4>\n<p>Google Cloud SDK'y\u0131 bilgisayar\u0131n\u0131za kurman\u0131z gerekmektedir. Kurulum talimatlar\u0131 i\u00e7in Google Cloud belgelerine bakabilirsiniz. Kurulumdan sonra terminalde kimlik do\u011frulamas\u0131 yap\u0131n:<\/p>\n<pre><code class=\"language-bash\">gcloud auth login\ngcloud config set project YOUR_PROJECT_ID\n<\/pre>\n<p><\/code><\/p>\n<p><code>YOUR_PROJECT_ID<\/code> yerine kendi Google Cloud proje ID'nizi yaz\u0131n.<\/p>\n<h4>Docker \u0130maj\u0131n\u0131 Olu\u015fturma ve Google Container Registry'ye Y\u00fckleme<\/h4>\n<p>Projenizin k\u00f6k dizininde a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131rarak Docker imaj\u0131n\u0131z\u0131 olu\u015fturun ve GCR'ye y\u00fckleyin. Bu i\u015flem Cloud Build taraf\u0131ndan y\u00f6netilir:<\/p>\n<pre><code class=\"language-bash\">gcloud builds submit --tag gcr.io\/YOUR_PROJECT_ID\/my-portfolio-map\n<\/pre>\n<p><\/code><\/p>\n<p>Bu komut, <code>Dockerfile<\/code>'\u0131n\u0131z\u0131 kullanarak bir Docker imaj\u0131 olu\u015fturacak, etiketleyecek ve Google Container Registry'ye (GCR) y\u00fckleyecektir. \u0130maj ad\u0131 <code>gcr.io\/YOUR_PROJECT_ID\/my-portfolio-map<\/code> \u015feklinde olacakt\u0131r.<\/p>\n<h4>Cloud Run Servisini Da\u011f\u0131tma ve Yap\u0131land\u0131rma<\/h4>\n<p>\u0130maj\u0131n\u0131z GCR'ye y\u00fcklendikten sonra, onu Cloud Run'a da\u011f\u0131tabilirsiniz:<\/p>\n<pre><code class=\"language-bash\">gcloud run deploy my-portfolio-map \\\n  --image gcr.io\/YOUR_PROJECT_ID\/my-portfolio-map \\\n  --platform managed \\\n  --region us-central1 \\\n  --allow-unauthenticated \\\n  --port 8080\n<\/pre>\n<p><\/code><\/p>\n<ul>\n<li><code>my-portfolio-map<\/code>: Cloud Run servisinizin ad\u0131d\u0131r.<\/li>\n<li><code>--image<\/code>: GCR'deki Docker imaj\u0131n\u0131z\u0131n yoludur.<\/li>\n<li><code>--platform managed<\/code>: Cloud Run'\u0131n tam olarak y\u00f6netilen ortam\u0131n\u0131 kullan\u0131r.<\/li>\n<li><code>--region us-central1<\/code>: Servisinizi da\u011f\u0131tmak istedi\u011finiz b\u00f6lgedir (size en yak\u0131n olan\u0131 se\u00e7ebilirsiniz).<\/li>\n<li><code>--allow-unauthenticated<\/code>: Servisinize herkese a\u00e7\u0131k eri\u015fime izin verir (portf\u00f6y haritas\u0131 i\u00e7in gereklidir).<\/li>\n<li><code>--port 8080<\/code>: Uygulaman\u0131z\u0131n i\u00e7inde dinledi\u011fi porttur (<code>Dockerfile<\/code>'da belirtti\u011fimiz <code>ENV PORT 8080<\/code> ile e\u015fle\u015fmelidir).<\/li>\n<\/ul>\n<p>Da\u011f\u0131t\u0131m tamamland\u0131\u011f\u0131nda, terminalde servisinizin URL'sini g\u00f6receksiniz. Bu URL'yi kullanarak interaktif portf\u00f6y haritan\u0131za eri\u015febilirsiniz. Cloud Run, gelen isteklere g\u00f6re uygulaman\u0131z\u0131 otomatik olarak \u00f6l\u00e7eklendirecek ve siz sadece kullan\u0131lan kaynaklar i\u00e7in \u00f6deme yapacaks\u0131n\u0131z.<\/p>\n<h3>Sonu\u00e7 ve Gelecek Ad\u0131mlar<\/h3>\n<p>Bu makalede, Next.js, React-Leaflet ve Google Cloud Run kullanarak nas\u0131l interaktif bir portf\u00f6y haritas\u0131 olu\u015fturaca\u011f\u0131n\u0131z\u0131 ve da\u011f\u0131taca\u011f\u0131n\u0131z\u0131 \u00f6\u011frendiniz. Bu proje, sadece teknik becerilerinizi sergilemekle kalmay\u0131p, ayn\u0131 zamanda yarat\u0131c\u0131 ve etkile\u015fimli bir deneyim sunarak izleyicilerinizin dikkatini \u00e7ekmenizi sa\u011flayacakt\u0131r.<\/p>\n<h4>\u00d6zet ve Elde Edilenler<\/h4>\n<p>Next.js'in modern web geli\u015ftirme yeteneklerinden faydalanarak h\u0131zl\u0131 ve SEO dostu bir uygulama olu\u015fturduk. React-Leaflet ile kolayca interaktif harita entegrasyonu sa\u011flad\u0131k ve projelerimizi co\u011frafi olarak g\u00f6rselle\u015ftirdik. Son olarak, Docker ve Google Cloud Run sayesinde uygulamam\u0131z\u0131 kolayca konteynerize edip sunucusuz bir ortamda \u00f6l\u00e7eklenebilir ve maliyet etkin bir \u015fekilde da\u011f\u0131tt\u0131k.<\/p>\n<h4>Performans Optimizasyonu ve G\u00fcvenlik \u0130pu\u00e7lar\u0131<\/h4>\n<ul>\n<li><strong>Harita Verilerini Optimize Edin:<\/strong> B\u00fcy\u00fck veri setleri i\u00e7in, sadece g\u00f6r\u00fcn\u00fcr alandaki i\u015faret\u00e7ileri y\u00fcklemek veya k\u00fcmeleme (clustering) teknikleri kullanmak performans\u0131 art\u0131rabilir.<\/li>\n<li><strong>Resimleri Optimize Edin:<\/strong> Portf\u00f6y detaylar\u0131nda kullanaca\u011f\u0131n\u0131z g\u00f6rselleri WebP gibi modern formatlarda ve optimize edilmi\u015f boyutlarda sunun.<\/li>\n<li><strong>G\u00fcvenlik Ba\u015fl\u0131klar\u0131:<\/strong> Next.js'in g\u00fcvenlik ba\u015fl\u0131klar\u0131n\u0131 (CSP, HSTS) yap\u0131land\u0131rarak uygulaman\u0131z\u0131n g\u00fcvenli\u011fini art\u0131r\u0131n.<\/li>\n<li><strong>Ortam De\u011fi\u015fkenleri:<\/strong> Hassas bilgileri (API anahtarlar\u0131 vb.) do\u011frudan koda g\u00f6mmek yerine, Google Cloud Secret Manager gibi hizmetler arac\u0131l\u0131\u011f\u0131yla ortam de\u011fi\u015fkenleri olarak y\u00f6netin.<\/li>\n<\/ul>\n<h4>Geli\u015ftirme \u0130\u00e7in Ek Fikirler<\/h4>\n<ul>\n<li><strong>Filtreleme ve Arama:<\/strong> Harita \u00fczerindeki projeleri kategoriye, tarihe veya anahtar kelimeye g\u00f6re filtreleme ve arama \u00f6zellikleri ekleyin.<\/li>\n<li><strong>Kullan\u0131c\u0131 Kimlik Do\u011frulamas\u0131:<\/strong> E\u011fer haritan\u0131zda ki\u015fiselle\u015ftirilmi\u015f i\u00e7erikler sunacaksan\u0131z, Firebase Authentication gibi servislerle kullan\u0131c\u0131 kimlik do\u011frulamas\u0131 ekleyebilirsiniz.<\/li>\n<li><strong>Daha Zengin Harita Katmanlar\u0131:<\/strong> Mapbox veya Google Maps gibi daha geli\u015fmi\u015f harita servislerini entegre ederek \u00f6zel harita stilleri ve daha zengin \u00f6zellikler sunabilirsiniz.<\/li>\n<li><strong>CI\/CD Boru Hatt\u0131:<\/strong> Cloud Build veya GitHub Actions gibi ara\u00e7larla otomatik da\u011f\u0131t\u0131m (CI\/CD) boru hatt\u0131 kurarak kod de\u011fi\u015fikliklerinizin otomatik olarak Cloud Run'a da\u011f\u0131t\u0131lmas\u0131n\u0131 sa\u011flay\u0131n.<\/li>\n<\/ul>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<h4>Next.js yerine ba\u015fka bir framework kullanabilir miyim?<\/h4>\n<p>Evet, React, Vue.js veya Angular gibi di\u011fer modern JavaScript framework'lerini de kullanabilirsiniz. Ancak Next.js, SSR ve SSG yetenekleriyle performans ve SEO avantajlar\u0131 sunar. Da\u011f\u0131t\u0131m s\u00fcreci (Docker ve Cloud Run) \u00e7o\u011fu framework i\u00e7in benzer olacakt\u0131r.<\/p>\n<h4>Hangi harita k\u00fct\u00fcphanesini se\u00e7meliyim?<\/h4>\n<p>Bu makalede React-Leaflet'i kulland\u0131k \u00e7\u00fcnk\u00fc hafif, a\u00e7\u0131k kaynakl\u0131 ve React ile iyi entegre olur. Alternatif olarak, daha fazla \u00f6zellik ve \u00f6zelle\u015ftirme se\u00e7ene\u011fi sunan Mapbox GL JS (react-map-gl ile) veya Google Maps API (react-google-maps ile) gibi k\u00fct\u00fcphaneleri de de\u011ferlendirebilirsiniz. Se\u00e7iminiz projenizin gereksinimlerine ve b\u00fct\u00e7enize ba\u011fl\u0131d\u0131r.<\/p>\n<h4>Google Cloud Run'\u0131n maliyeti ne kadar?<\/h4>\n<p>Google Cloud Run, c\u00f6mert bir \u00fccretsiz katman sunar. Bu katman, ayda belirli bir miktarda CPU s\u00fcresi, bellek ve istek say\u0131s\u0131n\u0131 kapsar. K\u00fc\u00e7\u00fck ve orta \u00f6l\u00e7ekli portf\u00f6y haritalar\u0131 i\u00e7in bu \u00fccretsiz katman genellikle yeterli olacakt\u0131r. Kullan\u0131m\u0131n\u0131z \u00fccretsiz katman\u0131 a\u015farsa, sadece kulland\u0131\u011f\u0131n\u0131z kaynaklar i\u00e7in \u00f6deme yapars\u0131n\u0131z. Fiyatland\u0131rma detaylar\u0131 i\u00e7in Google Cloud Run fiyatland\u0131rma sayfas\u0131n\u0131 kontrol edebilirsiniz.<\/p>\n<h4>Verilerimi nas\u0131l g\u00fcncel tutabilirim?<\/h4>\n<p>Verileriniz statik bir JSON dosyas\u0131ndaysa, dosyay\u0131 g\u00fcncelleyip uygulamay\u0131 yeniden da\u011f\u0131tman\u0131z gerekir. E\u011fer bir API veya headless CMS kullan\u0131yorsan\u0131z, CMS aray\u00fcz\u00fcnden verileri g\u00fcncelleyebilir ve uygulaman\u0131z\u0131n API'yi yeniden \u00e7a\u011f\u0131rmas\u0131n\u0131 sa\u011flayarak otomatik olarak yeni verileri g\u00f6stermesini sa\u011flayabilirsiniz. Bir CI\/CD boru hatt\u0131 kurarak, kod veya veri de\u011fi\u015fikliklerinin otomatik olarak yeni bir da\u011f\u0131t\u0131ma yol a\u00e7mas\u0131n\u0131 sa\u011flayabilirsiniz.<\/p>\n","protected":false},"excerpt":{"rendered":"Kariyeriniz boyunca farkl\u0131 \u015fehirlerde veya \u00fclkelerde ger\u00e7ekle\u015ftirdi\u011finiz projeleri, kat\u0131ld\u0131\u011f\u0131n\u0131z etkinlikleri veya edindi\u011finiz deneyimleri g\u00f6rse&#8230;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1341],"tags":[],"class_list":{"0":"post-38480","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-cloud","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run&#039;a Da\u011f\u0131tma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run&#039;a Da\u011f\u0131tma\" \/>\n<meta property=\"og:description\" content=\"Kariyeriniz boyunca farkl\u0131 \u015fehirlerde veya \u00fclkelerde ger\u00e7ekle\u015ftirdi\u011finiz projeleri, kat\u0131ld\u0131\u011f\u0131n\u0131z etkinlikleri veya edindi\u011finiz deneyimleri g\u00f6rse...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2026-02-01T04:30:38+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run&#8217;a Da\u011f\u0131tma\",\"datePublished\":\"2026-02-01T04:30:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/\"},\"wordCount\":2276,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Cloud\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/\",\"name\":\"Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run'a Da\u011f\u0131tma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2026-02-01T04:30:38+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run&#8217;a Da\u011f\u0131tma\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run'a Da\u011f\u0131tma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/","og_locale":"tr_TR","og_type":"article","og_title":"Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run'a Da\u011f\u0131tma","og_description":"Kariyeriniz boyunca farkl\u0131 \u015fehirlerde veya \u00fclkelerde ger\u00e7ekle\u015ftirdi\u011finiz projeleri, kat\u0131ld\u0131\u011f\u0131n\u0131z etkinlikleri veya edindi\u011finiz deneyimleri g\u00f6rse...","og_url":"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2026-02-01T04:30:38+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"14 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run&#8217;a Da\u011f\u0131tma","datePublished":"2026-02-01T04:30:38+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/"},"wordCount":2276,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Cloud"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/","url":"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/","name":"Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run'a Da\u011f\u0131tma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2026-02-01T04:30:38+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/next-js-ile-interaktif-portfoy-haritasi-olusturma-ve-google-cloud-runa-dagitma\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Next.js ile \u0130nteraktif Portf\u00f6y Haritas\u0131 Olu\u015fturma ve Google Cloud Run&#8217;a Da\u011f\u0131tma"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/38480","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=38480"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/38480\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=38480"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=38480"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=38480"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}