{"id":36863,"date":"2025-12-24T05:40:45","date_gmt":"2025-12-24T02:40:45","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=36863"},"modified":"2025-12-24T05:40:45","modified_gmt":"2025-12-24T02:40:45","slug":"prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/","title":{"rendered":"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma"},"content":{"rendered":"<p><body><\/p>\n<h2>Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma<\/h2>\n<p>Tek Sayfal\u0131 Uygulamalar (SPA&#8217;lar), modern web geli\u015ftirmenin temel ta\u015flar\u0131ndan biri haline gelmi\u015ftir. Vue.js, React ve Angular gibi g\u00fc\u00e7l\u00fc framework&#8217;ler sayesinde geli\u015ftiriciler, zengin, etkile\u015fimli ve dinamik kullan\u0131c\u0131 deneyimleri sunan uygulamalar olu\u015fturabilirler. Ancak, SPA&#8217;lar\u0131n getirdi\u011fi baz\u0131 zorluklar da bulunmaktad\u0131r, \u00f6zellikle Arama Motoru Optimizasyonu (SEO), ilk i\u00e7erik boyama (First Contentful Paint &#8211; FCP) performans\u0131 ve sosyal medya payla\u015f\u0131mlar\u0131 gibi alanlarda. Bu zorluklar\u0131n \u00fcstesinden gelmek i\u00e7in \u00f6nceden olu\u015fturma (prerendering) tekni\u011fi, giderek daha fazla pop\u00fclerlik kazanmaktad\u0131r. Bu makalede, Vue.js uygulamalar\u0131n\u0131z\u0131 <code>prerender-spa-plugin<\/code>&#8216;in v3 s\u00fcr\u00fcm\u00fcn\u00fc kullanarak nas\u0131l \u00f6nceden olu\u015fturaca\u011f\u0131n\u0131z\u0131, bu s\u00fcrecin avantajlar\u0131n\u0131, dezavantajlar\u0131n\u0131 ve en iyi uygulamalar\u0131n\u0131 detayl\u0131 bir \u015fekilde inceleyece\u011fiz.<\/p>\n<h3>Tek Sayfal\u0131 Uygulamalar\u0131n Zorluklar\u0131 ve \u00d6nceden Olu\u015fturman\u0131n \u00c7\u00f6z\u00fcmleri<\/h3>\n<p>SPA&#8217;lar, taray\u0131c\u0131da JavaScript arac\u0131l\u0131\u011f\u0131yla dinamik olarak i\u00e7erik olu\u015fturan uygulamalard\u0131r. Bu yakla\u015f\u0131m, sayfa yenilemeleri olmadan h\u0131zl\u0131 ge\u00e7i\u015fler ve ak\u0131c\u0131 bir kullan\u0131c\u0131 deneyimi sa\u011flar. Ancak, bu dinamik yap\u0131 baz\u0131 \u00f6nemli sorunlara yol a\u00e7abilir:<\/p>\n<h4>SEO Sorunlar\u0131<\/h4>\n<p>Geleneksel olarak, arama motoru taray\u0131c\u0131lar\u0131 (crawler&#8217;lar), bir web sayfas\u0131n\u0131 ziyaret ettiklerinde HTML i\u00e7eri\u011fini okur ve dizine ekler. SPA&#8217;lar ise genellikle ba\u015flang\u0131\u00e7ta bo\u015f veya minimal bir HTML dosyas\u0131 (\u00f6rne\u011fin, yaln\u0131zca bir <code><\/p>\n<div id=\"app\"><\/div>\n<p><\/code> etiketi) sunar. \u0130\u00e7erik, JavaScript y\u00fcklendikten ve \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131ktan sonra DOM&#8217;a eklenir. Modern arama motorlar\u0131 (\u00f6zellikle Google), JavaScript&#8217;i i\u015fleme konusunda \u00f6nemli ilerlemeler kaydetmi\u015f olsa da, bu s\u00fcre\u00e7 zaman al\u0131c\u0131 olabilir ve her zaman m\u00fckemmel sonu\u00e7lar vermeyebilir. Di\u011fer arama motorlar\u0131 veya daha eski taray\u0131c\u0131lar i\u00e7in bu durum ciddi bir dezavantajd\u0131r. Sonu\u00e7 olarak, uygulaman\u0131z\u0131n i\u00e7eri\u011fi arama motorlar\u0131 taraf\u0131ndan do\u011fru bir \u015fekilde dizine eklenmeyebilir, bu da organik trafik kayb\u0131na yol a\u00e7ar.<\/p>\n<h4>Performans ve \u0130lk \u0130\u00e7erik Boyama (FCP)<\/h4>\n<p>Kullan\u0131c\u0131 bir SPA&#8217;y\u0131 ziyaret etti\u011finde, taray\u0131c\u0131 \u00f6nce HTML, CSS ve JavaScript dosyalar\u0131n\u0131 indirir. JavaScript dosyalar\u0131 b\u00fcy\u00fck olabilir ve taray\u0131c\u0131n\u0131n bunlar\u0131 indirmesi, ayr\u0131\u015ft\u0131rmas\u0131 ve \u00e7al\u0131\u015ft\u0131rmas\u0131 zaman alabilir. Bu s\u00fcre zarf\u0131nda kullan\u0131c\u0131, bo\u015f bir beyaz ekran veya y\u00fckleme g\u00f6stergesi g\u00f6rebilir. Bu durum, &#8220;\u0130lk \u0130\u00e7erik Boyama&#8221; (FCP) s\u00fcresini uzat\u0131r ve k\u00f6t\u00fc bir kullan\u0131c\u0131 deneyimi yarat\u0131r. H\u0131zl\u0131 y\u00fcklenen sayfalar, kullan\u0131c\u0131 memnuniyetini art\u0131r\u0131r ve hemen \u00e7\u0131kma oranlar\u0131n\u0131 d\u00fc\u015f\u00fcr\u00fcr.<\/p>\n<h4>Sosyal Medya Payla\u015f\u0131mlar\u0131<\/h4>\n<p>Sosyal medya platformlar\u0131 (Facebook, Twitter, LinkedIn vb.), bir ba\u011flant\u0131 payla\u015f\u0131ld\u0131\u011f\u0131nda sayfan\u0131n \u00f6nizlemesini olu\u015fturmak i\u00e7in genellikle kendi taray\u0131c\u0131lar\u0131n\u0131 (scraper&#8217;lar\u0131n\u0131) kullan\u0131r. Bu scraper&#8217;lar, genellikle JavaScript&#8217;i tam olarak \u00e7al\u0131\u015ft\u0131rmaz veya beklenen \u015fekilde i\u015flemez. Bu da, payla\u015f\u0131lan ba\u011flant\u0131lar\u0131n bo\u015f ba\u015fl\u0131klar, eksik a\u00e7\u0131klamalar veya yanl\u0131\u015f resimlerle g\u00f6r\u00fcnmesine neden olabilir, bu da sosyal medya pazarlamas\u0131 ve payla\u015f\u0131labilirli\u011fi a\u00e7\u0131s\u0131ndan olumsuz bir etki yarat\u0131r.<\/p>\n<h4>\u00d6nceden Olu\u015fturman\u0131n \u00c7\u00f6z\u00fcm\u00fc<\/h4>\n<p>\u00d6nceden olu\u015fturma (prerendering), bu sorunlara zarif bir \u00e7\u00f6z\u00fcm sunar. Uygulaman\u0131z\u0131n belirli rotalar\u0131n\u0131 derleme (build) zaman\u0131nda statik HTML dosyalar\u0131na d\u00f6n\u00fc\u015ft\u00fcrerek \u00e7al\u0131\u015f\u0131r. Yani, her bir \u00f6nceden olu\u015fturulmu\u015f rota i\u00e7in, JavaScript \u00e7al\u0131\u015fmadan \u00f6nce bile i\u00e7eri\u011fi dolu olan ayr\u0131 bir HTML dosyas\u0131 olu\u015fturulur.<\/p>\n<p>*   <strong>SEO i\u00e7in:<\/strong> Arama motoru taray\u0131c\u0131lar\u0131, do\u011frudan i\u00e7eri\u011fi dolu HTML dosyalar\u0131n\u0131 g\u00f6r\u00fcr ve dizine ekler.<br \/>\n*   <strong>Performans i\u00e7in:<\/strong> Kullan\u0131c\u0131lar, JavaScript&#8217;in y\u00fcklenmesini beklemeden an\u0131nda i\u00e7eri\u011fi g\u00f6r\u00fcr. Bu, FCP s\u00fcresini \u00f6nemli \u00f6l\u00e7\u00fcde iyile\u015ftirir. JavaScript daha sonra y\u00fcklenir ve uygulaman\u0131n etkile\u015fimli hale gelmesini sa\u011flar (hidrasyon).<br \/>\n*   <strong>Sosyal Medya i\u00e7in:<\/strong> Sosyal medya scraper&#8217;lar\u0131, zengin meta etiketleri ve do\u011fru i\u00e7eri\u011fe sahip HTML dosyalar\u0131n\u0131 okuyabilir, b\u00f6ylece payla\u015f\u0131mlar\u0131n\u0131z do\u011fru \u015fekilde g\u00f6r\u00fcn\u00fcr.<\/p>\n<h3>\u00d6nceden Olu\u015fturma (Prerendering) Nedir?<\/h3>\n<p>\u00d6nceden olu\u015fturma, bir web uygulamas\u0131n\u0131n belirli rotalar\u0131n\u0131n statik HTML dosyalar\u0131na d\u00f6n\u00fc\u015ft\u00fcr\u00fclmesi i\u015flemidir. Bu i\u015flem, uygulaman\u0131n derleme a\u015famas\u0131nda ger\u00e7ekle\u015fir. Bir taray\u0131c\u0131 ortam\u0131 (genellikle Headless Chrome gibi bir ba\u015fs\u0131z taray\u0131c\u0131) kullan\u0131larak belirtilen rotalar ziyaret edilir, sayfa tamamen y\u00fcklendikten sonra olu\u015fturulan HTML \u00e7\u0131kt\u0131s\u0131 al\u0131n\u0131r ve statik bir dosya olarak kaydedilir.<\/p>\n<h4>SSR (Sunucu Tarafl\u0131 Olu\u015fturma) ile Fark\u0131<\/h4>\n<p>\u00d6nceden olu\u015fturma, genellikle Sunucu Tarafl\u0131 Olu\u015fturma (SSR) ile kar\u0131\u015ft\u0131r\u0131l\u0131r, ancak aralar\u0131nda \u00f6nemli farklar vard\u0131r:<\/p>\n<p>*   <strong>SSR (Server-Side Rendering):<\/strong> Her bir kullan\u0131c\u0131 iste\u011fi i\u00e7in sunucuda sayfa olu\u015fturulur. Bu, dinamik ve kullan\u0131c\u0131ya \u00f6zel i\u00e7erik i\u00e7in idealdir. Ancak, sunucu taraf\u0131nda ek y\u00fck ve daha karma\u015f\u0131k bir kurulum gerektirir.<br \/>\n*   <strong>Prerendering:<\/strong> Uygulama derleme zaman\u0131nda (build time) yaln\u0131zca belirli rotalar i\u00e7in statik HTML dosyalar\u0131 olu\u015fturulur. Bu dosyalar daha sonra bir CDN veya basit bir statik dosya sunucusu \u00fczerinden sunulur. Sunucu taraf\u0131nda ek bir i\u015flem y\u00fck\u00fc yoktur.<\/p>\n<p><strong>Ne Zaman Hangisini Kullanmal\u0131?<\/strong><\/p>\n<p>*   <strong>Prerendering:<\/strong> \u0130\u00e7eri\u011fi \u00e7o\u011funlukla statik olan, nadiren de\u011fi\u015fen veya ki\u015fiselle\u015ftirme gerektirmeyen sayfalar (hakk\u0131m\u0131zda, ileti\u015fim, blog g\u00f6nderileri, \u00fcr\u00fcn sayfalar\u0131 gibi) i\u00e7in m\u00fckemmeldir. Kurulumu daha basittir ve daha ucuz bar\u0131nd\u0131rma se\u00e7enekleri sunar.<br \/>\n*   <strong>SSR:<\/strong> \u0130\u00e7eri\u011fi s\u0131k\u00e7a de\u011fi\u015fen, kullan\u0131c\u0131ya \u00f6zel dinamik veriler i\u00e7eren veya \u00e7ok say\u0131da rotaya sahip uygulamalar (sosyal medya ak\u0131\u015flar\u0131, e-ticaret sepetleri, kullan\u0131c\u0131 panelleri gibi) i\u00e7in daha uygundur.<\/p>\n<h3>Prerender-SPA-Plugin&#8217;e Giri\u015f<\/h3>\n<p><code>prerender-spa-plugin<\/code>, Vue.js (veya herhangi bir SPA framework&#8217;\u00fc) uygulamalar\u0131n\u0131 derleme zaman\u0131nda \u00f6nceden olu\u015fturmak i\u00e7in tasarlanm\u0131\u015f bir Webpack eklentisidir. Bu eklenti, Headless Chrome&#8217;u (Puppeteer arac\u0131l\u0131\u011f\u0131yla) kullanarak uygulaman\u0131z\u0131n belirtilen rotalar\u0131n\u0131 ziyaret eder, JavaScript \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131ktan sonra ortaya \u00e7\u0131kan HTML&#8217;yi yakalar ve bunu statik HTML dosyalar\u0131 olarak kaydeder.<\/p>\n<p><code>prerender-spa-plugin<\/code> v3 s\u00fcr\u00fcm\u00fc, Puppeteer tabanl\u0131 bir render motoru kullan\u0131r. Bu, modern JavaScript \u00f6zelliklerini ve taray\u0131c\u0131 davran\u0131\u015flar\u0131n\u0131 daha iyi desteklemesini sa\u011flar. Ayr\u0131ca, daha esnek konfig\u00fcrasyon se\u00e7enekleri ve hata ay\u0131klama yetenekleri sunar.<\/p>\n<h3>Vue.js Projesinde Kurulum ve Temel Yap\u0131land\u0131rma<\/h3>\n<p>Standart bir Vue CLI projesinde <code>prerender-spa-plugin<\/code>&#8216;i entegre etmek olduk\u00e7a basittir.<\/p>\n<h4>1. Kurulum<\/h4>\n<p>\u00d6ncelikle, eklentiyi projenize geli\u015ftirme ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 olarak y\u00fcklemeniz gerekir:<\/p>\n<pre><code class=\"language-bash\">npm install prerender-spa-plugin@^3.0.0 --save-dev\n<h2>veya<\/h2>\nyarn add prerender-spa-plugin@^3.0.0 --dev<\/code><\/pre>\n<p><code>@^3.0.0<\/code> eklemek, \u00f6zellikle v3 s\u00fcr\u00fcm\u00fcn\u00fc y\u00fcklemenizi sa\u011flar, \u00e7\u00fcnk\u00fc v2 ile v3 aras\u0131nda baz\u0131 API farkl\u0131l\u0131klar\u0131 bulunmaktad\u0131r.<\/p>\n<h4>2. Vue.config.js Dosyas\u0131n\u0131 Yap\u0131land\u0131rma<\/h4>\n<p>Vue CLI, Webpack yap\u0131land\u0131rmas\u0131n\u0131 <code>vue.config.js<\/code> dosyas\u0131 arac\u0131l\u0131\u011f\u0131yla \u00f6zelle\u015ftirmenize olanak tan\u0131r. Bu dosyada, <code>prerender-spa-plugin<\/code>&#8216;i Webpack eklentileri listesine ekleyece\u011fiz. E\u011fer <code>vue.config.js<\/code> dosyan\u0131z yoksa, projenizin k\u00f6k dizininde olu\u015fturun.<\/p>\n<pre><code class=\"language-javascript\">\/\/ vue.config.js\nconst path = require('path');\nconst PrerenderSPAPlugin = require('prerender-spa-plugin');\n\nmodule.exports = {\n  \/\/ Vue CLI'nin kendi Webpack yap\u0131land\u0131rmas\u0131n\u0131 geni\u015fletmek i\u00e7in configureWebpack kullan\u0131r\u0131z.\n  configureWebpack: () => {\n    if (process.env.NODE_ENV !== 'production') return {}; \/\/ Sadece production build'\u0131nda \u00e7al\u0131\u015ft\u0131r\n\n    return {\n      plugins: [\n        new PrerenderSPAPlugin({\n          \/\/ prerendered dosyalar\u0131n\u0131n kaydedilece\u011fi dizin\n          staticDir: path.resolve(__dirname, 'dist'),\n          \/\/ \u00d6nceden olu\u015fturulacak rotalar\n          routes: ['\/', '\/hakkimizda', '\/iletisim'],\n          \n          \/\/ Renderer yap\u0131land\u0131rmas\u0131 (Puppeteer varsay\u0131lan olarak kullan\u0131l\u0131r)\n          renderer: new PrerenderSPAPlugin.PuppeteerRenderer({\n            \/\/ Sayfa y\u00fcklendikten sonra belirli bir DOM olay\u0131n\u0131 beklemek i\u00e7in\n            \/\/ renderAfterDocumentEvent: 'render-ready', \n            \n            \/\/ Sayfa y\u00fcklendikten sonra belirli bir \u00f6\u011fenin var olmas\u0131n\u0131 beklemek i\u00e7in\n            \/\/ renderAfterElementExists: '#app', \n            \n            \/\/ Sayfa y\u00fcklendikten sonra belirli bir s\u00fcre beklemek i\u00e7in (milisaniye cinsinden)\n            renderAfterTime: 5000, \/\/ \u00d6rnek: 5 saniye bekle\n            \n            \/\/ Puppeteer'a \u00f6zel arg\u00fcmanlar\n            args: ['--no-sandbox', '--disable-setuid-sandbox'],\n            \n            \/\/ Headless modda \u00e7al\u0131\u015ft\u0131r (varsay\u0131lan: true)\n            \/\/ headless: false, \/\/ Hata ay\u0131klama i\u00e7in false yap\u0131labilir\n          })\n        })\n      ]\n    };\n  }\n};<\/code><\/pre>\n<p><strong>A\u00e7\u0131klama:<\/strong><\/p>\n<p>*   <code>path.resolve(__dirname, 'dist')<\/code>: <code>staticDir<\/code> se\u00e7ene\u011fi, \u00f6nceden olu\u015fturulmu\u015f HTML dosyalar\u0131n\u0131n kaydedilece\u011fi dizini belirtir. Vue CLI&#8217;nin varsay\u0131lan \u00e7\u0131kt\u0131 dizini <code>dist<\/code> oldu\u011fundan, bu yolu kullan\u0131r\u0131z.<br \/>\n*   <code>routes: ['\/', '\/hakkimizda', '\/iletisim']<\/code>: Bu, \u00f6nceden olu\u015fturulmas\u0131n\u0131 istedi\u011finiz URL yollar\u0131n\u0131n bir dizisidir. Her bir rota i\u00e7in ayr\u0131 bir HTML dosyas\u0131 olu\u015fturulacakt\u0131r (\u00f6rne\u011fin, <code>\/dist\/index.html<\/code>, <code>\/dist\/hakkimizda\/index.html<\/code>, <code>\/dist\/iletisim\/index.html<\/code>).<br \/>\n*   <code>renderer: new PrerenderSPAPlugin.PuppeteerRenderer({...})<\/code>: Bu, eklentinin sayfalar\u0131 nas\u0131l olu\u015fturaca\u011f\u0131n\u0131 yap\u0131land\u0131rd\u0131\u011f\u0131m\u0131z yerdir. <code>PuppeteerRenderer<\/code> varsay\u0131lan ve \u00f6nerilen render motorudur.<\/p>\n<p>    *   <code>renderAfterTime: 5000<\/code>: Bu, sayfan\u0131n tamamen y\u00fcklendi\u011finden emin olmak i\u00e7in kritik bir se\u00e7enektir. Uygulaman\u0131z\u0131n t\u00fcm JavaScript&#8217;ini \u00e7al\u0131\u015ft\u0131rmas\u0131 ve veri \u00e7ekme i\u015flemlerini tamamlamas\u0131 i\u00e7in yeterli bir s\u00fcre tan\u0131r. E\u011fer verileriniz asenkron olarak y\u00fckleniyorsa, bu s\u00fcreyi art\u0131rman\u0131z gerekebilir. Alternatif olarak, <code>renderAfterDocumentEvent<\/code> veya <code>renderAfterElementExists<\/code> se\u00e7eneklerini kullanabilirsiniz.<br \/>\n    *   <code>args: ['--no-sandbox', '--disable-setuid-sandbox']<\/code>: \u00d6zellikle CI\/CD ortamlar\u0131nda veya Linux sunucular\u0131nda Puppeteer&#8217;\u0131n do\u011fru \u00e7al\u0131\u015fmas\u0131 i\u00e7in bu arg\u00fcmanlar genellikle gereklidir. G\u00fcvenlik nedeniyle <code>--no-sandbox<\/code> kullan\u0131lmas\u0131 tavsiye edilir.<\/p>\n<p>Bu yap\u0131land\u0131rma ile, <code>npm run build<\/code> komutunu \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131n\u0131zda, Webpack uygulaman\u0131z\u0131 derleyecek ve ard\u0131ndan <code>prerender-spa-plugin<\/code> devreye girerek belirtilen rotalar i\u00e7in statik HTML dosyalar\u0131n\u0131 <code>dist<\/code> dizinine kaydedecektir.<\/p>\n<h3>Geli\u015fmi\u015f Yap\u0131land\u0131rma Se\u00e7enekleri<\/h3>\n<p><code>prerender-spa-plugin<\/code> v3, daha karma\u015f\u0131k senaryolar i\u00e7in bir dizi geli\u015fmi\u015f yap\u0131land\u0131rma se\u00e7ene\u011fi sunar.<\/p>\n<h4>Renderer Se\u00e7enekleri (<code>PrerenderSPAPlugin.PuppeteerRenderer<\/code>)<\/h4>\n<p>*   <code>renderAfterDocumentEvent: 'my-custom-event'<\/code>: Uygulaman\u0131zda belirli bir DOM olay\u0131n\u0131 tetikledikten sonra prerendering&#8217;in bitmesini bekler. \u00d6rne\u011fin, Vue uygulaman\u0131z t\u00fcm verileri y\u00fckledikten sonra <code>document.dispatchEvent(new Event('render-ready'))<\/code> \u015feklinde bir olay tetikleyebilirsiniz. Bu, <code>renderAfterTime<\/code>&#8216;dan daha g\u00fcvenilir bir y\u00f6ntemdir.<br \/>\n*   <code>renderAfterElementExists: '#app-root'<\/code> veya <code>renderAfterElementExists: '.my-content-loaded-class'<\/code>: Belirli bir DOM \u00f6\u011fesinin sayfada g\u00f6r\u00fcnmesini bekler. Bu, i\u00e7eri\u011fin y\u00fcklendi\u011fini g\u00f6steren bir elementiniz oldu\u011funda kullan\u0131\u015fl\u0131d\u0131r.<br \/>\n*   <code>maxAttempts: 3<\/code>: Bir rota i\u00e7in olu\u015fturma i\u015flemi ba\u015far\u0131s\u0131z olursa ka\u00e7 kez yeniden denenece\u011fini belirtir.<br \/>\n*   <code>timeout: 60000<\/code>: Bir rotan\u0131n olu\u015fturulmas\u0131 i\u00e7in maksimum bekleme s\u00fcresi (milisaniye). Varsay\u0131lan 60 saniyedir.<br \/>\n*   <code>headless: true\/false<\/code>: Puppeteer&#8217;\u0131n ba\u015fs\u0131z modda (arka planda) m\u0131 yoksa g\u00f6rsel bir pencerede mi \u00e7al\u0131\u015faca\u011f\u0131n\u0131 belirler. <code>false<\/code> olarak ayarlamak, hata ay\u0131klama s\u0131ras\u0131nda ne oldu\u011funu g\u00f6rmenizi sa\u011flar.<br \/>\n*   <code>inject: { foo: 'bar' }<\/code>: Prerender edilen sayfaya global de\u011fi\u015fkenler enjekte eder. Bu de\u011fi\u015fkenlere <code>window.foo<\/code> gibi eri\u015filebilir. Bu, prerender s\u0131ras\u0131nda uygulaman\u0131z\u0131n davran\u0131\u015f\u0131n\u0131 de\u011fi\u015ftirmek i\u00e7in kullan\u0131labilir.<br \/>\n*   <code>skipThirdPartyRequests: true<\/code>: Performans\u0131 art\u0131rmak i\u00e7in \u00fc\u00e7\u00fcnc\u00fc taraf isteklerini (\u00f6rne\u011fin, CDN&#8217;lerden gelen fontlar, analitik betikleri) engeller. Bu, prerendering s\u00fcresini k\u0131saltabilir.<br \/>\n*   <code>viewport: { width: 1280, height: 800 }<\/code>: Puppeteer taraf\u0131ndan kullan\u0131lan viewport boyutlar\u0131n\u0131 ayarlar.<\/p>\n<h4>Genel Plugin Se\u00e7enekleri<\/h4>\n<p>*   <code>postProcess: (context) => { ... }<\/code>: Prerendered HTML \u00fczerinde son i\u015flem yapmak i\u00e7in kullan\u0131l\u0131r. <code>context<\/code> nesnesi <code>html<\/code>, <code>route<\/code>, <code>originalRoute<\/code>, <code>outputPath<\/code> gibi bilgileri i\u00e7erir. \u00d6rne\u011fin, belirli script etiketlerini kald\u0131rmak veya ek meta etiketleri eklemek i\u00e7in kullan\u0131labilir.<\/p>\n<pre><code class=\"language-javascript\">postProcess: (context) => {\n      \/\/ Google Analytics scriptini kald\u0131r\n      context.html = context.html.replace(\/<script[^>]<em>src=\"https:\\\/\\\/www.googletagmanager.com\\\/gtag\\\/js[^>]<\/em>><\\\/script>\/g, '');\n      \/\/ Uygulama ba\u015flatma scriptini ertele\n      context.html = context.html.replace('id=\"app\"><\/div>', 'id=\"app\"><\/div><script src=\"\/js\/app.js\" defer><\/script>');\n      return context;\n    }<\/code><\/pre>\n<p>*   <code>minify: { ... }<\/code>: Prerendered HTML&#8217;yi s\u0131k\u0131\u015ft\u0131rmak i\u00e7in <code>html-minifier<\/code> se\u00e7eneklerini kullan\u0131r. Bu, dosya boyutunu k\u00fc\u00e7\u00fclt\u00fcr.<\/p>\n<pre><code class=\"language-javascript\">minify: {\n      collapseBooleanAttributes: true,\n      collapseWhitespace: true,\n      decodeEntities: true,\n      keepClosingSlash: true,\n      sortAttributes: true\n    }<\/code><\/pre>\n<h3>Pratik \u00d6rnek Uygulama<\/h3>\n<p>\u015eimdi, basit bir Vue.js uygulamas\u0131 \u00fczerinde <code>prerender-spa-plugin<\/code>&#8216;in nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 ad\u0131m ad\u0131m g\u00f6relim.<\/p>\n<h4>1. Vue Projesi Olu\u015fturma<\/h4>\n<p>E\u011fer hen\u00fcz bir Vue projeniz yoksa, Vue CLI ile yeni bir proje olu\u015fturun:<\/p>\n<pre><code class=\"language-bash\">vue create my-prerender-app\ncd my-prerender-app<\/code><\/pre>\n<p>Router&#8217;\u0131 (Vue Router) eklemeyi unutmay\u0131n.<\/p>\n<h4>2. Basit Bile\u015fenler ve Rotalar Olu\u015fturma<\/h4>\n<p><code>src\/views<\/code> dizininde veya benzer bir yerde birka\u00e7 basit bile\u015fen olu\u015ftural\u0131m:<\/p>\n<p><strong><code>src\/views\/Home.vue<\/code><\/strong><\/p>\n<pre><code class=\"language-vue\"><template>\n  <div>\n    \n    <p>Uygulamam\u0131z\u0131n ana sayfas\u0131.<\/p>\n    <router-link to=\"\/hakkimizda\">Hakk\u0131m\u0131zda<\/router-link> |\n    <router-link to=\"\/iletisim\">\u0130leti\u015fim<\/router-link>\n  <\/div>\n<\/template><\/code><\/pre>\n<p><strong><code>src\/views\/About.vue<\/code><\/strong><\/p>\n<pre><code class=\"language-vue\"><template>\n  <div>\n    \n    <p>Bu, \u015firketimiz hakk\u0131nda bilgi veren sayfad\u0131r.<\/p>\n  <\/div>\n<\/template><\/code><\/pre>\n<p><strong><code>src\/views\/Contact.vue<\/code><\/strong><\/p>\n<pre><code class=\"language-vue\"><template>\n  <div>\n    \n    <p>Bizimle ileti\u015fime ge\u00e7mek i\u00e7in bu sayfay\u0131 kullan\u0131n.<\/p>\n  <\/div>\n<\/template><\/code><\/pre>\n<p><strong><code>src\/router\/index.js<\/code><\/strong> (Vue Router yap\u0131land\u0131rmas\u0131)<\/p>\n<pre><code class=\"language-javascript\">import { createRouter, createWebHistory } from 'vue-router';\nimport Home from '..\/views\/Home.vue';\nimport About from '..\/views\/About.vue';\nimport Contact from '..\/views\/Contact.vue';\n\nconst routes = [\n  {\n    path: '\/',\n    name: 'Home',\n    component: Home\n  },\n  {\n    path: '\/hakkimizda',\n    name: 'About',\n    component: About\n  },\n  {\n    path: '\/iletisim',\n    name: 'Contact',\n    component: Contact\n  }\n];\n\nconst router = createRouter({\n  history: createWebHistory(process.env.BASE_URL),\n  routes\n});\n\nexport default router;<\/code><\/pre>\n<h4>3. <code>prerender-spa-plugin<\/code> Kurulumu ve Yap\u0131land\u0131rmas\u0131<\/h4>\n<p>Yukar\u0131daki kurulum ad\u0131mlar\u0131n\u0131 izleyerek <code>prerender-spa-plugin<\/code>&#8216;i y\u00fckleyin ve <code>vue.config.js<\/code> dosyan\u0131z\u0131 yap\u0131land\u0131r\u0131n.<\/p>\n<pre><code class=\"language-javascript\">\/\/ vue.config.js\nconst path = require('path');\nconst PrerenderSPAPlugin = require('prerender-spa-plugin');\n\nmodule.exports = {\n  configureWebpack: () => {\n    if (process.env.NODE_ENV !== 'production') return {};\n\n    return {\n      plugins: [\n        new PrerenderSPAPlugin({\n          staticDir: path.resolve(__dirname, 'dist'),\n          routes: ['\/', '\/hakkimizda', '\/iletisim'], \/\/ Olu\u015fturdu\u011fumuz rotalar\n          renderer: new PrerenderSPAPlugin.PuppeteerRenderer({\n            renderAfterTime: 5000, \n            args: ['--no-sandbox', '--disable-setuid-sandbox'],\n          })\n        })\n      ]\n    };\n  }\n};<\/code><\/pre>\n<h4>4. Uygulamay\u0131 Derleme<\/h4>\n<p>\u015eimdi uygulamay\u0131 derleyin:<\/p>\n<pre><code class=\"language-bash\">npm run build<\/code><\/pre>\n<p>Derleme i\u015flemi tamamland\u0131ktan sonra, <code>dist<\/code> klas\u00f6r\u00fcn\u00fc inceleyin. \u015eunlar\u0131 g\u00f6rmelisiniz:<\/p>\n<p>*   <code>dist\/index.html<\/code> (Ana sayfa i\u00e7in)<br \/>\n*   <code>dist\/hakkimizda\/index.html<\/code> (Hakk\u0131m\u0131zda sayfas\u0131 i\u00e7in)<br \/>\n*   <code>dist\/iletisim\/index.html<\/code> (\u0130leti\u015fim sayfas\u0131 i\u00e7in)<\/p>\n<p>Bu HTML dosyalar\u0131n\u0131 bir metin d\u00fczenleyici ile a\u00e7t\u0131\u011f\u0131n\u0131zda, i\u00e7lerinde ilgili Vue bile\u015fenlerinin statik HTML i\u00e7eri\u011fini g\u00f6receksiniz. \u00d6rne\u011fin, <code>dist\/hakkimizda\/index.html<\/code> dosyas\u0131n\u0131n i\u00e7eri\u011fi \u015f\u00f6yle bir \u015fey i\u00e7erecektir:<\/p>\n<pre><code class=\"language-html\"><!DOCTYPE html>\n<html lang=\"\">\n  <head>\n    <!-- ... meta etiketleri ... -->\n    <title>My Prerender App<\/title>\n  <\/head>\n  <body>\n    <noscript>\n      <strong>We're sorry but my-prerender-app doesn't work properly without JavaScript enabled. Please enable it to continue.<\/strong>\n    <\/noscript>\n    <div id=\"app\" data-v-app=\"\">\n      <div>\n        \n        <p>Bu, \u015firketimiz hakk\u0131nda bilgi veren sayfad\u0131r.<\/p>\n      <\/div>\n    <\/div>\n    <!-- ... script etiketleri ... -->\n  <\/body>\n<\/html><\/code><\/pre>\n<p><code>div id=\"app\"<\/code> etiketinin i\u00e7inde art\u0131k uygulaman\u0131n i\u00e7eri\u011fi yer almaktad\u0131r. Bu, arama motorlar\u0131n\u0131n ve sosyal medya scraper&#8217;lar\u0131n\u0131n do\u011frudan okuyabilece\u011fi statik HTML&#8217;dir. JavaScript y\u00fcklendikten sonra Vue.js, bu \u00f6nceden olu\u015fturulmu\u015f DOM \u00fczerinde &#8220;hidrasyon&#8221; yaparak uygulamay\u0131 etkile\u015fimli hale getirecektir.<\/p>\n<h3>En \u0130yi Uygulamalar ve Dikkat Edilmesi Gerekenler<\/h3>\n<p><code>prerender-spa-plugin<\/code> kullan\u0131rken dikkate alman\u0131z gereken baz\u0131 en iyi uygulamalar ve potansiyel tuzaklar vard\u0131r:<\/p>\n<h4>Dinamik Rotalar ve Veri \u00c7ekme<\/h4>\n<p>*   <strong>Sabit Rotalar \u0130\u00e7in Ideal:<\/strong> Prerendering, \u00f6nceden bilinen ve nispeten statik i\u00e7erik sunan rotalar i\u00e7in en uygundur. \u00d6rne\u011fin, bir blog uygulamas\u0131nda her blog g\u00f6nderisi i\u00e7in ayr\u0131 bir rota (\u00f6rne\u011fin <code>\/blog\/post-1<\/code>, <code>\/blog\/post-2<\/code>) varsa, bu rotalar\u0131n her birini <code>routes<\/code> dizisine manuel olarak eklemeniz gerekir.<br \/>\n*   <strong>API Verilerinin Beklenmesi:<\/strong> Uygulaman\u0131z API&#8217;lerden veri \u00e7ekiyorsa, prerendering i\u015flemi bu veriler y\u00fcklendikten sonra tamamlanmal\u0131d\u0131r. Aksi takdirde, olu\u015fturulan HTML bo\u015f i\u00e7erik i\u00e7erebilir. <code>renderAfterTime<\/code>, <code>renderAfterDocumentEvent<\/code> veya <code>renderAfterElementExists<\/code> se\u00e7eneklerini kullanarak t\u00fcm verilerin y\u00fcklenmesini bekledi\u011finizden emin olun. <code>renderAfterDocumentEvent<\/code> genellikle en g\u00fcvenilir y\u00f6ntemdir; t\u00fcm asenkron i\u015flemler bittikten sonra \u00f6zel bir olay tetikleyebilirsiniz.<br \/>\n*   <strong>Sunucu Taraf\u0131nda Kullan\u0131lan Veri:<\/strong> Baz\u0131 durumlarda, prerendering s\u0131ras\u0131nda uygulaman\u0131z\u0131n sunucu taraf\u0131nda kullan\u0131lan verileri (\u00f6rne\u011fin, API anahtarlar\u0131) kullanmas\u0131 gerekebilir. <code>inject<\/code> se\u00e7ene\u011fi ile bu t\u00fcr verileri sayfaya enjekte edebilirsiniz, ancak hassas bilgileri do\u011frudan if\u015fa etmemeye dikkat edin.<\/p>\n<h4>Client-Side Hydration (M\u00fc\u015fteri Taraf\u0131 Hidrasyon)<\/h4>\n<p>*   <strong>Tutarl\u0131l\u0131k:<\/strong> Prerendered HTML, uygulaman\u0131z\u0131n istemci taraf\u0131nda olu\u015fturdu\u011fu DOM yap\u0131s\u0131yla birebir ayn\u0131 olmal\u0131d\u0131r. K\u00fc\u00e7\u00fck farkl\u0131l\u0131klar bile Vue.js&#8217;nin hidrasyon i\u015flemini bozabilir ve uygulaman\u0131n yeniden olu\u015fturulmas\u0131na neden olabilir, bu da performans avantaj\u0131n\u0131 ortadan kald\u0131r\u0131r. \u00d6zellikle <code>v-if<\/code>, <code>v-show<\/code> gibi direktiflerin prerender s\u0131ras\u0131nda nas\u0131l davrand\u0131\u011f\u0131na dikkat edin.<br \/>\n*   <strong><code>window<\/code> Nesnesi:<\/strong> Prerendering, Node.js ortam\u0131nda (Puppeteer arac\u0131l\u0131\u011f\u0131yla) ger\u00e7ekle\u015fti\u011fi i\u00e7in, <code>window<\/code> veya <code>document<\/code> gibi taray\u0131c\u0131ya \u00f6zg\u00fc global nesnelere do\u011frudan eri\u015fmeye \u00e7al\u0131\u015fan kodlar hata verebilir. Bu t\u00fcr kodlar\u0131 yaln\u0131zca taray\u0131c\u0131 ortam\u0131nda \u00e7al\u0131\u015facak \u015fekilde ko\u015fullu olarak sarmalay\u0131n.<\/p>\n<h4>Derleme S\u00fcresi ve Kaynak T\u00fcketimi<\/h4>\n<p>*   <strong>Artan Derleme S\u00fcresi:<\/strong> Her bir rotan\u0131n Headless Chrome&#8217;da olu\u015fturulmas\u0131 zaman alacakt\u0131r. \u00c7ok say\u0131da rotan\u0131z varsa, derleme s\u00fcresi \u00f6nemli \u00f6l\u00e7\u00fcde uzayabilir.<br \/>\n*   <strong>Bellek T\u00fcketimi:<\/strong> Puppeteer, \u00f6zellikle \u00e7ok say\u0131da rota i\u00e7in veya karma\u015f\u0131k sayfalar olu\u015ftururken \u00f6nemli miktarda bellek t\u00fcketebilir. CI\/CD ortamlar\u0131nda bellek limitlerini g\u00f6z \u00f6n\u00fcnde bulundurun.<br \/>\n*   <strong>Sadece \u00dcretim Ortam\u0131:<\/strong> <code>configureWebpack<\/code> i\u00e7inde <code>process.env.NODE_ENV !== 'production'<\/code> kontrol\u00fcn\u00fc kullanarak <code>prerender-spa-plugin<\/code>&#8216;in yaln\u0131zca \u00fcretim derlemelerinde \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flamak iyi bir uygulamad\u0131r. Geli\u015ftirme s\u0131ras\u0131nda prerendering&#8217;e ihtiyac\u0131n\u0131z yoktur.<\/p>\n<h4>Hata Ay\u0131klama<\/h4>\n<p>*   <code>headless: false<\/code>: Hata ay\u0131klama s\u0131ras\u0131nda <code>PuppeteerRenderer<\/code> yap\u0131land\u0131rmas\u0131nda <code>headless: false<\/code> yaparak Puppeteer&#8217;\u0131n g\u00f6rsel bir pencerede \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flayabilirsiniz. Bu, bir sayfan\u0131n neden do\u011fru \u015fekilde olu\u015fturulmad\u0131\u011f\u0131n\u0131 veya belirli bir \u00f6\u011fenin neden bulunamad\u0131\u011f\u0131n\u0131 g\u00f6rmenize yard\u0131mc\u0131 olur.<br \/>\n*   <code>console.log<\/code>: Prerendering s\u0131ras\u0131nda taray\u0131c\u0131 konsoluna yaz\u0131lan mesajlar, derleme \u00e7\u0131kt\u0131s\u0131nda g\u00f6r\u00fcnecektir. Bu, sorunlar\u0131 te\u015fhis etmek i\u00e7in kullan\u0131labilir.<\/p>\n<h4>Deployment (Da\u011f\u0131t\u0131m)<\/h4>\n<p>*   <strong>Statik Sunucular:<\/strong> Prerendered bir Vue.js uygulamas\u0131, herhangi bir statik dosya sunucusu (Nginx, Apache, Netlify, Vercel, Firebase Hosting, GitHub Pages vb.) \u00fczerinden kolayca da\u011f\u0131t\u0131labilir. <code>dist<\/code> klas\u00f6r\u00fcndeki t\u00fcm dosyalar\u0131 sunucuya y\u00fcklemeniz yeterlidir.<br \/>\n*   <strong>URL Yap\u0131s\u0131:<\/strong> Prerender-spa-plugin, <code>\/hakkimizda<\/code> rotas\u0131 i\u00e7in <code>\/hakkimizda\/index.html<\/code> \u015feklinde bir dizin yap\u0131s\u0131 olu\u015fturur. Bu, bir\u00e7ok statik sunucunun varsay\u0131lan olarak <code>\/hakkimizda<\/code> iste\u011fini <code>\/hakkimizda\/index.html<\/code>&#8216;e y\u00f6nlendirmesiyle uyumludur.<\/p>\n<h3>S\u0131n\u0131rlamalar<\/h3>\n<p><code>prerender-spa-plugin<\/code> g\u00fc\u00e7l\u00fc bir ara\u00e7 olsa da, her senaryo i\u00e7in uygun de\u011fildir:<\/p>\n<p>*   <strong>Y\u00fcksek Derecede Dinamik \u0130\u00e7erik:<\/strong> Her kullan\u0131c\u0131 i\u00e7in farkl\u0131 veya s\u00fcrekli de\u011fi\u015fen i\u00e7erik sunan uygulamalar i\u00e7in prerendering uygun de\u011fildir. Bu t\u00fcr durumlar i\u00e7in SSR veya istemci taraf\u0131nda dinamik y\u00fckleme daha iyi se\u00e7eneklerdir.<br \/>\n*   <strong>\u00c7ok Say\u0131da Dinamik Rota:<\/strong> Y\u00fcz binlerce \u00fcr\u00fcn sayfas\u0131 gibi \u00e7ok say\u0131da dinamik rotaya sahip bir e-ticaret sitesi i\u00e7in t\u00fcm rotalar\u0131 derleme zaman\u0131nda prerender etmek pratik veya verimli olmayabilir.<br \/>\n*   <strong>Etkile\u015fimden Sonra De\u011fi\u015fen \u0130\u00e7erik:<\/strong> E\u011fer sayfan\u0131n \u00f6nemli bir k\u0131sm\u0131 kullan\u0131c\u0131 etkile\u015fiminden sonra (\u00f6rne\u011fin, bir form g\u00f6nderildikten sonra) de\u011fi\u015fiyorsa, prerendered HTML bu de\u011fi\u015fiklikleri yans\u0131tmayacakt\u0131r.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p><code>prerender-spa-plugin<\/code> v3, Vue.js uygulamalar\u0131n\u0131z\u0131n SEO performans\u0131n\u0131, ilk y\u00fckleme h\u0131z\u0131n\u0131 ve sosyal medya payla\u015f\u0131mlar\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde iyile\u015ftirmek i\u00e7in harika bir ara\u00e7t\u0131r. \u00d6zellikle i\u00e7eri\u011fi nispeten statik olan bloglar, kurumsal web siteleri, \u00fcr\u00fcn sayfalar\u0131 veya pazarlama odakl\u0131 a\u00e7\u0131l\u0131\u015f sayfalar\u0131 gibi senaryolar i\u00e7in idealdir.<\/p>\n<p>Bu eklentiyi kullanarak, uygulaman\u0131z\u0131n en \u00f6nemli rotalar\u0131n\u0131 derleme zaman\u0131nda statik, i\u00e7eri\u011fi dolu HTML dosyalar\u0131na d\u00f6n\u00fc\u015ft\u00fcrebilirsiniz. Bu sayede, arama motorlar\u0131 i\u00e7eri\u011finizi kolayca dizine ekleyebilir, kullan\u0131c\u0131lar bo\u015f bir ekran yerine an\u0131nda i\u00e7erikle kar\u015f\u0131la\u015f\u0131r ve sosyal medya payla\u015f\u0131mlar\u0131n\u0131z daha \u00e7ekici hale gelir. <code>prerender-spa-plugin<\/code>&#8216;in esnek yap\u0131land\u0131rma se\u00e7enekleri sayesinde, uygulaman\u0131z\u0131n \u00f6zel ihtiya\u00e7lar\u0131na g\u00f6re prerendering s\u00fcrecini optimize edebilirsiniz. Do\u011fru kullan\u0131ld\u0131\u011f\u0131nda, bu eklenti modern SPA geli\u015ftirme s\u00fcrecinde \u00f6nemli bir performans ve eri\u015filebilirlik art\u0131\u015f\u0131 sa\u011flayabilir.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma\nTek Sayfal\u0131 Uygulamalar (SPA&#8217;lar), modern web geli\u015ftirmenin temel ta\u015flar\u0131","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":[1402],"tags":[],"class_list":{"0":"post-36863","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-vue","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>Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma - 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\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma\" \/>\n<meta property=\"og:description\" content=\"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma Tek Sayfal\u0131 Uygulamalar (SPA&#039;lar), modern web geli\u015ftirmenin temel ta\u015flar\u0131\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-24T02:40:45+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=\"16 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma\",\"datePublished\":\"2025-12-24T02:40:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/\"},\"wordCount\":2693,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Vue\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/\",\"name\":\"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-12-24T02:40:45+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma\"}]},{\"@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":"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma - 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\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/","og_locale":"tr_TR","og_type":"article","og_title":"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma","og_description":"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma Tek Sayfal\u0131 Uygulamalar (SPA'lar), modern web geli\u015ftirmenin temel ta\u015flar\u0131","og_url":"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-12-24T02:40:45+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"16 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma","datePublished":"2025-12-24T02:40:45+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/"},"wordCount":2693,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Vue"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/","url":"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/","name":"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-12-24T02:40:45+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/prerender-spa-plugin-v3-ile-vue-js-uygulamalarini-onceden-olusturma\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Prerender-SPA-Plugin v3 ile Vue.js Uygulamalar\u0131n\u0131 \u00d6nceden Olu\u015fturma"}]},{"@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\/36863","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=36863"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/36863\/revisions"}],"predecessor-version":[{"id":36864,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/36863\/revisions\/36864"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=36863"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=36863"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=36863"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}