[{"data":1,"prerenderedAt":355},["ShallowReactive",2],{"article-\u002Fblog\u002Fnuxt-ssr-websites-on-netlify-functions":3},{"article":4,"author":324},{"id":5,"title":6,"author":7,"body":8,"date":306,"description":307,"extension":308,"image":309,"imageAlt":310,"imageHeight":311,"imageWidth":312,"meta":313,"navigation":314,"path":315,"seo":316,"stem":317,"subhead":318,"tags":319,"__hash__":323},"blog\u002Fblog\u002Fnuxt-ssr-websites-on-netlify-functions.md","Server-Rendered Nuxt Websites on Netlify Functions","forbes-gray",{"type":9,"value":10,"toc":295},"minimark",[11,15,29,34,42,48,51,55,58,61,64,68,71,201,208,212,216,226,229,236,240,243,259,262,273,276,280,283,291],[12,13,14],"p",{},"For a long time my answer to \"how should we build this website?\" was simple: build it\nas a fast static site. Every page is generated ahead of time, uploaded to a global\nnetwork of servers, and delivered to visitors almost instantly. For a brochure website\nthat changes once a month, that is still hard to beat.",[12,16,17,18,23,24,28],{},"But not every website is a brochure. Some need to show stock levels that change hourly,\ncontent that depends on who is logged in, or pages that the business wants to publish\nthe moment they hit save. For those, I now build server-side rendered (SSR) Nuxt\nwebsites that run on Netlify Functions. Two recent projects,\n",[19,20,22],"a",{"href":21},"\u002Fportfolio\u002Fwebsite\u002Ffnbg-ltd\u002F","FNBG Business Telecoms"," and the\n",[19,25,27],{"href":26},"\u002Fportfolio\u002Fecommerce\u002Fgsd-trade\u002F","GSD Trade"," wholesale platform, work exactly this way.",[30,31,33],"h2",{"id":32},"static-vs-server-rendered-in-plain-english","Static vs Server-Rendered, in Plain English",[12,35,36,37,41],{},"A ",[38,39,40],"strong",{},"static site"," is like a printed brochure. Every page is produced in advance, and\neveryone gets the same copy. To change anything, you reprint (rebuild) the whole thing.",[12,43,36,44,47],{},[38,45,46],{},"server-rendered site"," is more like a member of staff answering the phone. Each\ntime a page is requested, the server puts it together there and then, using the latest\ncontent and, if needed, details about the person asking.",[12,49,50],{},"The difference for visitors is that a server-rendered page is always up to date. The\ndifference for search engines is nothing at all: both approaches send complete,\nready-to-read HTML, which is exactly what Google wants.",[30,52,54],{"id":53},"where-netlify-functions-come-in","Where Netlify Functions Come In",[12,56,57],{},"Traditionally, server rendering meant renting a server, keeping it patched and secure,\nand paying for it around the clock whether anyone visited or not. That overhead is the\nmain reason small businesses were steered towards static sites in the first place.",[12,59,60],{},"Netlify Functions remove that overhead. They are small pieces of server code that only\nrun when a request comes in, then switch off again. There is no server to look after,\nthey scale automatically if a page suddenly gets busy, and for most small business\nwebsites the usage sits comfortably within Netlify's free or entry-level plans.",[12,62,63],{},"Nuxt makes this almost effortless. Its server engine, Nitro, detects when a site is\nbeing built on Netlify and packages the server-rendering code as a Netlify Function\nautomatically. Images, scripts and styles are still served straight from Netlify's\nglobal CDN, and only the page rendering itself runs in the function.",[30,65,67],{"id":66},"the-best-of-both-hybrid-rendering","The Best of Both: Hybrid Rendering",[12,69,70],{},"The real strength of Nuxt is that you don't have to choose one approach for the whole\nsite. Each route can be rendered in the way that suits it best:",[72,73,78],"pre",{"className":74,"code":75,"language":76,"meta":77,"style":77},"language-ts shiki shiki-themes github-light github-dark","\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  routeRules: {\n    \u002F\u002F Rarely changes: build it once, serve it statically\n    '\u002Fabout\u002F': { prerender: true },\n    \u002F\u002F Content from the CMS: render on the server, then cache it for an hour\n    '\u002Fservices\u002F**': { isr: 3600 },\n    \u002F\u002F Personal to each customer: always render fresh, never cache\n    '\u002Faccount\u002F**': { ssr: true, headers: { 'cache-control': 'no-store' } },\n  },\n})\n","ts","",[79,80,81,90,108,114,120,137,143,157,163,189,195],"code",{"__ignoreMap":77},[82,83,86],"span",{"class":84,"line":85},"line",1,[82,87,89],{"class":88},"sJ8bj","\u002F\u002F nuxt.config.ts\n",[82,91,93,97,100,104],{"class":84,"line":92},2,[82,94,96],{"class":95},"szBVR","export",[82,98,99],{"class":95}," default",[82,101,103],{"class":102},"sScJk"," defineNuxtConfig",[82,105,107],{"class":106},"sVt8B","({\n",[82,109,111],{"class":84,"line":110},3,[82,112,113],{"class":106},"  routeRules: {\n",[82,115,117],{"class":84,"line":116},4,[82,118,119],{"class":88},"    \u002F\u002F Rarely changes: build it once, serve it statically\n",[82,121,123,127,130,134],{"class":84,"line":122},5,[82,124,126],{"class":125},"sZZnC","    '\u002Fabout\u002F'",[82,128,129],{"class":106},": { prerender: ",[82,131,133],{"class":132},"sj4cs","true",[82,135,136],{"class":106}," },\n",[82,138,140],{"class":84,"line":139},6,[82,141,142],{"class":88},"    \u002F\u002F Content from the CMS: render on the server, then cache it for an hour\n",[82,144,146,149,152,155],{"class":84,"line":145},7,[82,147,148],{"class":125},"    '\u002Fservices\u002F**'",[82,150,151],{"class":106},": { isr: ",[82,153,154],{"class":132},"3600",[82,156,136],{"class":106},[82,158,160],{"class":84,"line":159},8,[82,161,162],{"class":88},"    \u002F\u002F Personal to each customer: always render fresh, never cache\n",[82,164,166,169,172,174,177,180,183,186],{"class":84,"line":165},9,[82,167,168],{"class":125},"    '\u002Faccount\u002F**'",[82,170,171],{"class":106},": { ssr: ",[82,173,133],{"class":132},[82,175,176],{"class":106},", headers: { ",[82,178,179],{"class":125},"'cache-control'",[82,181,182],{"class":106},": ",[82,184,185],{"class":125},"'no-store'",[82,187,188],{"class":106}," } },\n",[82,190,192],{"class":84,"line":191},10,[82,193,194],{"class":106},"  },\n",[82,196,198],{"class":84,"line":197},11,[82,199,200],{"class":106},"})\n",[12,202,203,204,207],{},"That ",[79,205,206],{},"isr"," rule is the one that makes server rendering feel as fast as a static site.\nThe first visitor to a page triggers the function, Netlify keeps the result in its\ncache, and everyone after that gets the cached copy straight from the CDN until it\nexpires. It's the same speed as a static site, but content updates appear without\na full rebuild.",[30,209,211],{"id":210},"real-examples","Real Examples",[213,214,22],"h3",{"id":215},"fnbg-business-telecoms",[12,217,218,219,225],{},"The ",[19,220,224],{"href":221,"rel":222},"https:\u002F\u002Fwww.fnbg.co.uk",[223],"nofollow","FNBG website"," is built with Nuxt, Tailwind and DatoCMS.\nPages are rendered on the server from the content in the CMS and then held in\nNetlify's cache, so almost every visitor is served a cached page from the CDN rather\nthan waiting for it to be built. Because the pages are rendered from the CMS rather\nthan baked into a build, content changes don't depend on rebuilding the whole site.",[213,227,27],{"id":228},"gsd-trade",[12,230,231,235],{},[19,232,27],{"href":233,"rel":234},"https:\u002F\u002Fwww.gsdtrade.co.uk",[223]," is a trade-only ecommerce platform where\ncustomers log in to an account to shop. Much of what a logged-in customer sees, such as\ntheir account and orders, is specific to them, so it can't be generated once and given\nto everyone. Server rendering on Netlify Functions lets those pages be built per\nrequest, talking to the ElasticPath commerce API and DatoCMS behind the scenes, while\npublic pages like the homepage and product information can still be cached for speed.",[30,237,239],{"id":238},"is-it-right-for-your-website","Is It Right for Your Website?",[12,241,242],{},"Server rendering on Netlify Functions is a great fit when:",[244,245,246,250,253,256],"ul",{},[247,248,249],"li",{},"Your content changes often and you want updates to appear straight away",[247,251,252],{},"Customers log in and see information specific to them",[247,254,255],{},"You have prices, stock or other data that a static build would quickly get out of\nstep with",[247,257,258],{},"You have a large catalogue where rebuilding every page for each change becomes slow",[12,260,261],{},"A fully static site is still the better choice when:",[244,263,264,267,270],{},[247,265,266],{},"The site is small and rarely changes",[247,268,269],{},"You want the absolute simplest setup with the fewest moving parts",[247,271,272],{},"Every visitor sees exactly the same content",[12,274,275],{},"There are a couple of trade-offs to be aware of. A function that hasn't run for a while\ncan take a moment longer to respond the first time (a \"cold start\"), which is why\ncaching matters so much. Functions also have a time limit per request, so anything slow,\nlike generating large reports, is better handled in the background.",[30,277,279],{"id":278},"summary","Summary",[12,281,282],{},"Server-rendered Nuxt on Netlify Functions gives you the things that used to need a\ndedicated server, like live content, logged-in areas and dynamic pricing, without the\ncost or upkeep of running one. Combined with sensible caching, the result is a website\nthat is as fast as a static site, always up to date, and still cheap to host.",[12,284,285,286,290],{},"If you are weighing up whether your next website should be static or server-rendered,\n",[19,287,289],{"href":288},"\u002Fcontact\u002F","get in touch"," and I'll happily talk through which approach suits your\nbusiness.",[292,293,294],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":77,"searchDepth":92,"depth":92,"links":296},[297,298,299,300,304,305],{"id":32,"depth":92,"text":33},{"id":53,"depth":92,"text":54},{"id":66,"depth":92,"text":67},{"id":210,"depth":92,"text":211,"children":301},[302,303],{"id":215,"depth":110,"text":22},{"id":228,"depth":110,"text":27},{"id":238,"depth":92,"text":239},{"id":278,"depth":92,"text":279},"2026-11-10","How a server-side rendered Nuxt website runs on Netlify Functions, when it beats a purely static site, and how caching keeps it fast. With examples from the FNBG and GSD Trade websites.","md","\u002Fimages\u002Fprojects\u002Fweb-application\u002Fgsd-trade-mockup.png","The GSD Trade website, a server-rendered Nuxt site running on Netlify",1080,1920,{},true,"\u002Fblog\u002Fnuxt-ssr-websites-on-netlify-functions",{"title":6,"description":307},"blog\u002Fnuxt-ssr-websites-on-netlify-functions","Fast pages, live content and no server to manage",[320,321,322],"nuxt","netlify","ecommerce-sites","L4IXAyQdvXFTBGwrhb4GoX51ejDvSWxBop-B2eJMZo8",{"id":325,"title":326,"body":327,"description":334,"extension":308,"favoriteFoods":335,"image":338,"imageAlt":339,"interests":340,"links":345,"meta":348,"name":326,"navigation":314,"path":349,"position":350,"seo":351,"stem":352,"x":353,"__hash__":354},"team\u002Fmeet-the-team\u002Fforbes-gray.md","Forbes Gray",{"type":9,"value":328,"toc":332},[329],[12,330,331],{},"Forbes is a Freelance Website Developer based in Edinburgh, Scotland.",{"title":77,"searchDepth":92,"depth":92,"links":333},[],"Forbes Gray is a Website Developer from Edinburgh, Scotland, specialising in creating bespoke, fast & responsive modern websites & applications.",[336,337],"Anything Spicy","Twiglets","\u002Fimages\u002Fforbes-up-arthurs-seat.jpg","Forbes up Arthur's Seat",[341,342,343,344],"Football","Long Walks","Music","All Things Tech",[346,347],"https:\u002F\u002Fuk.linkedin.com\u002Fin\u002Fforbesgray","https:\u002F\u002Fx.com\u002F4beez",{},"\u002Fmeet-the-team\u002Fforbes-gray","Owner, Front & Back-end Developer, Customer Service, Accountant, Cleaner",{"title":326,"description":334},"meet-the-team\u002Fforbes-gray","@4beez","f7BCEIQUYrcK_PfNNMXc5JlTyxbnIg1zJpI-5PJnihE",1794329442483]