[{"data":1,"prerenderedAt":895},["ShallowReactive",2],{"blog-\u002Fblog\u002Fprerendering-all-routes-by-default-with-nuxt-content":3,"$f3j4m1caf4jl83":889},{"id":4,"title":5,"author":6,"backfeed":7,"body":9,"date":878,"description":879,"draft":8,"extension":880,"meta":881,"navigation":187,"path":882,"reply":883,"seo":884,"shortId":885,"sitemap":886,"stem":887,"__hash__":888},"blog\u002Fblog\u002Fprerendering-all-routes-by-default-with-nuxt-content.md","Prerendering All Routes By Default With Nuxt Content","Sylvester Duda",{"twitter":8,"github":8,"mastodon":8,"flickr":8},false,{"type":10,"value":11,"toc":875},"minimark",[12,36,131,134,139,147,155,161,309,316,322,343,346,571,580,583,865,871],[13,14,15,16,20,21,24,25,28,29,31,32,35],"p",{},"When I was first using ",[17,18,19],"code",{},"@nuxt\u002Fcontent"," I had trouble figuring out how to render my blog posts. My Nuxt Static site was building correctly, but none of the routes seemed to be getting included. If you are like I was, frustrated that things were not working, you've come to the right place. The issue is that the Nuxt crawler does not know about the routes in the ",[17,22,23],{},"\u002Fcontent"," directory it only knows about the routes in ",[17,26,27],{},"\u002Fpages",". The crawler looks for links mentioned in the built routes and builds those routes as well. This may be why you might have noticed some ",[17,30,23],{}," routes being included in the final build and others not being included. The workaround is to hard-code all of these routes in your ",[17,33,34],{},"nuxt.config.ts"," file like so:",[37,38,43],"pre",{"className":39,"code":40,"language":41,"meta":42,"style":42},"language-ts shiki shiki-themes one-dark-pro","\u002F\u002F https:\u002F\u002Fv3.nuxtjs.org\u002Fapi\u002Fconfiguration\u002Fnuxt.config\nexport default defineNuxtConfig({\n    nitro: {\n        prerender: {      \n            routes: ['\u002Fblog\u002Fpost1.md', '\u002Fblog\u002Fpost2.md'] \n        },\n    }\n}\n","ts","",[17,44,45,54,72,82,91,113,119,125],{"__ignoreMap":42},[46,47,50],"span",{"class":48,"line":49},"line",1,[46,51,53],{"class":52},"sV9Aq","\u002F\u002F https:\u002F\u002Fv3.nuxtjs.org\u002Fapi\u002Fconfiguration\u002Fnuxt.config\n",[46,55,57,61,64,68],{"class":48,"line":56},2,[46,58,60],{"class":59},"seHd6","export",[46,62,63],{"class":59}," default",[46,65,67],{"class":66},"sVbv2"," defineNuxtConfig",[46,69,71],{"class":70},"sn6KH","({\n",[46,73,75,79],{"class":48,"line":74},3,[46,76,78],{"class":77},"sVyAn","    nitro",[46,80,81],{"class":70},": {\n",[46,83,85,88],{"class":48,"line":84},4,[46,86,87],{"class":77},"        prerender",[46,89,90],{"class":70},": {      \n",[46,92,94,97,100,104,107,110],{"class":48,"line":93},5,[46,95,96],{"class":77},"            routes",[46,98,99],{"class":70},": [",[46,101,103],{"class":102},"subq3","'\u002Fblog\u002Fpost1.md'",[46,105,106],{"class":70},", ",[46,108,109],{"class":102},"'\u002Fblog\u002Fpost2.md'",[46,111,112],{"class":70},"] \n",[46,114,116],{"class":48,"line":115},6,[46,117,118],{"class":70},"        },\n",[46,120,122],{"class":48,"line":121},7,[46,123,124],{"class":70},"    }\n",[46,126,128],{"class":48,"line":127},8,[46,129,130],{"class":70},"}\n",[13,132,133],{},"This isn't ideal (at least for me) because in the future I want to build a CLI that allows me to generate a blog template and have it work out of the box on my next static build without having to try to manipulate any other files. So here's how to do it.",[135,136,138],"h2",{"id":137},"the-solution","The Solution",[13,140,141,142,146],{},"We could write a bash script that travels through the content directory ",[143,144,145],"em",{},"OR"," we could take another route and do this insido of Node. To do this we need to install Glob a library that allows us to have access to similar pattern matching that we have in the command line. To get started:",[37,148,153],{"className":149,"code":151,"language":152},[150],"language-text","npm install --save-dev glob\n","text",[17,154,151],{"__ignoreMap":42},[13,156,157,158,160],{},"The next thing we'll do is import it in our ",[17,159,34],{}," and start using it to see how we might be able to leverage it directly inside of our config.",[37,162,164],{"className":39,"code":163,"language":41,"meta":42,"style":42},"import glob from 'glob';\n\nconst files = glob.sync('content' + '\u002F**\u002F*')\nconsole.log(files)\n\n\u002F\u002F https:\u002F\u002Fv3.nuxtjs.org\u002Fapi\u002Fconfiguration\u002Fnuxt.config\nexport default defineNuxtConfig({\n    nitro: {\n        prerender: {      \n            routes: ['\u002Fblog\u002Fpost1.md', '\u002Fblog\u002Fpost2.md', ...files]\n        },\n    }\n}\n",[17,165,166,183,189,225,242,246,250,260,266,273,294,299,304],{"__ignoreMap":42},[46,167,168,171,174,177,180],{"class":48,"line":49},[46,169,170],{"class":59},"import",[46,172,173],{"class":77}," glob",[46,175,176],{"class":59}," from",[46,178,179],{"class":102}," 'glob'",[46,181,182],{"class":70},";\n",[46,184,185],{"class":48,"line":56},[46,186,188],{"emptyLinePlaceholder":187},true,"\n",[46,190,191,194,198,202,204,207,210,213,216,219,222],{"class":48,"line":74},[46,192,193],{"class":59},"const",[46,195,197],{"class":196},"sU0A5"," files",[46,199,201],{"class":200},"sjrmR"," =",[46,203,173],{"class":196},[46,205,206],{"class":70},".",[46,208,209],{"class":66},"sync",[46,211,212],{"class":70},"(",[46,214,215],{"class":102},"'content'",[46,217,218],{"class":200}," +",[46,220,221],{"class":102}," '\u002F**\u002F*'",[46,223,224],{"class":70},")\n",[46,226,227,230,232,235,237,240],{"class":48,"line":84},[46,228,229],{"class":196},"console",[46,231,206],{"class":70},[46,233,234],{"class":66},"log",[46,236,212],{"class":70},[46,238,239],{"class":77},"files",[46,241,224],{"class":70},[46,243,244],{"class":48,"line":93},[46,245,188],{"emptyLinePlaceholder":187},[46,247,248],{"class":48,"line":115},[46,249,53],{"class":52},[46,251,252,254,256,258],{"class":48,"line":121},[46,253,60],{"class":59},[46,255,63],{"class":59},[46,257,67],{"class":66},[46,259,71],{"class":70},[46,261,262,264],{"class":48,"line":127},[46,263,78],{"class":77},[46,265,81],{"class":70},[46,267,269,271],{"class":48,"line":268},9,[46,270,87],{"class":77},[46,272,90],{"class":70},[46,274,276,278,280,282,284,286,289,291],{"class":48,"line":275},10,[46,277,96],{"class":77},[46,279,99],{"class":70},[46,281,103],{"class":102},[46,283,106],{"class":70},[46,285,109],{"class":102},[46,287,288],{"class":70},", ...",[46,290,239],{"class":77},[46,292,293],{"class":70},"]\n",[46,295,297],{"class":48,"line":296},11,[46,298,118],{"class":70},[46,300,302],{"class":48,"line":301},12,[46,303,124],{"class":70},[46,305,307],{"class":48,"line":306},13,[46,308,130],{"class":70},[13,310,311,312,315],{},"One issue we have is that we don't need to prepend each route with ",[17,313,314],{},"content",". Another issue is the routes that we are including. With the following directory:",[37,317,320],{"className":318,"code":319,"language":152},[150],"\u002Fcontent\n|---\u002Fblog\n    |---post1.md\n    |---post1.md\n",[17,321,319],{"__ignoreMap":42},[13,323,324,325,328,329,331,332,335,336,338,339,342],{},"Our files array would include ",[17,326,327],{},"\u002Fblog"," in the list of files as well. If we already have a Nuxt Page for ",[17,330,327],{}," this would be fine and Nuxt would see the route in the ",[17,333,334],{},"pages"," directory, but if we did not, we would be telling nuxt to render a route that does not exist since ",[17,337,327],{}," is a directory and not a file. Along with that if we have any other file types (for whatever reason) like ",[17,340,341],{},".jpg"," inside of our content folder we would run into the same issue.",[13,344,345],{},"To fix this, we need to do some filtering:",[37,347,349],{"className":39,"code":348,"language":41,"meta":42,"style":42},"\u002F\u002F These are Contents supported formats\nconst formats = ['.md', '.json', '.csv', 'yml']\n\nconst files = glob.sync('content' + '\u002F**\u002F*')\ncontentFiles = files\n    .map(dir => dir.replace('content', ''))\n    .filter(dir => formats.some(ft => dir.endsWith(ft)))\n    .map(dir => dir.replace(\u002F\\.[^\u002F.]+$\u002F, \"\"));\nconsole.log(contentFiles)\n",[17,350,351,356,388,392,416,426,463,504,557],{"__ignoreMap":42},[46,352,353],{"class":48,"line":49},[46,354,355],{"class":52},"\u002F\u002F These are Contents supported formats\n",[46,357,358,360,363,365,368,371,373,376,378,381,383,386],{"class":48,"line":56},[46,359,193],{"class":59},[46,361,362],{"class":196}," formats",[46,364,201],{"class":200},[46,366,367],{"class":70}," [",[46,369,370],{"class":102},"'.md'",[46,372,106],{"class":70},[46,374,375],{"class":102},"'.json'",[46,377,106],{"class":70},[46,379,380],{"class":102},"'.csv'",[46,382,106],{"class":70},[46,384,385],{"class":102},"'yml'",[46,387,293],{"class":70},[46,389,390],{"class":48,"line":74},[46,391,188],{"emptyLinePlaceholder":187},[46,393,394,396,398,400,402,404,406,408,410,412,414],{"class":48,"line":84},[46,395,193],{"class":59},[46,397,197],{"class":196},[46,399,201],{"class":200},[46,401,173],{"class":196},[46,403,206],{"class":70},[46,405,209],{"class":66},[46,407,212],{"class":70},[46,409,215],{"class":102},[46,411,218],{"class":200},[46,413,221],{"class":102},[46,415,224],{"class":70},[46,417,418,421,423],{"class":48,"line":93},[46,419,420],{"class":77},"contentFiles",[46,422,201],{"class":200},[46,424,425],{"class":77}," files\n",[46,427,428,431,434,436,440,443,446,448,451,453,455,457,460],{"class":48,"line":115},[46,429,430],{"class":70},"    .",[46,432,433],{"class":66},"map",[46,435,212],{"class":70},[46,437,439],{"class":438},"s_ZVi","dir",[46,441,442],{"class":59}," =>",[46,444,445],{"class":196}," dir",[46,447,206],{"class":70},[46,449,450],{"class":66},"replace",[46,452,212],{"class":70},[46,454,215],{"class":102},[46,456,106],{"class":70},[46,458,459],{"class":102},"''",[46,461,462],{"class":70},"))\n",[46,464,465,467,470,472,474,476,478,480,483,485,488,490,492,494,497,499,501],{"class":48,"line":121},[46,466,430],{"class":70},[46,468,469],{"class":66},"filter",[46,471,212],{"class":70},[46,473,439],{"class":438},[46,475,442],{"class":59},[46,477,362],{"class":196},[46,479,206],{"class":70},[46,481,482],{"class":66},"some",[46,484,212],{"class":70},[46,486,487],{"class":438},"ft",[46,489,442],{"class":59},[46,491,445],{"class":196},[46,493,206],{"class":70},[46,495,496],{"class":66},"endsWith",[46,498,212],{"class":70},[46,500,487],{"class":77},[46,502,503],{"class":70},")))\n",[46,505,506,508,510,512,514,516,518,520,522,524,527,530,534,537,539,541,544,547,549,551,554],{"class":48,"line":127},[46,507,430],{"class":70},[46,509,433],{"class":66},[46,511,212],{"class":70},[46,513,439],{"class":438},[46,515,442],{"class":59},[46,517,445],{"class":196},[46,519,206],{"class":70},[46,521,450],{"class":66},[46,523,212],{"class":70},[46,525,526],{"class":77},"\u002F",[46,528,529],{"class":200},"\\.",[46,531,533],{"class":532},"sVC51","[",[46,535,536],{"class":70},"^",[46,538,526],{"class":532},[46,540,206],{"class":77},[46,542,543],{"class":532},"]+",[46,545,546],{"class":59},"$",[46,548,526],{"class":77},[46,550,106],{"class":70},[46,552,553],{"class":102},"\"\"",[46,555,556],{"class":70},"));\n",[46,558,559,561,563,565,567,569],{"class":48,"line":268},[46,560,229],{"class":196},[46,562,206],{"class":70},[46,564,234],{"class":66},[46,566,212],{"class":70},[46,568,420],{"class":77},[46,570,224],{"class":70},[13,572,573,574,576,577,579],{},"The first map gets rid of the ",[17,575,314],{}," portion of the directory. The filter makes sure that any file not supported by ",[17,578,19],{}," is not included in the array. The last map gets rid of our file type at the end of the file.",[13,581,582],{},"Our code should now look like the following:",[37,584,586],{"className":39,"code":585,"language":41,"meta":42,"style":42},"import glob from 'glob';\n\nconst files = glob.sync('content' + '\u002F**\u002F*')\n\n\u002F\u002F These are Contents supported formats\nconst formats = ['.md', '.json', '.csv', 'yml']\nconst files = glob.sync('content' + '\u002F**\u002F*')\nconst contentFiles = files\n    .map(dir => dir.replace('content', ''))\n    .filter(dir => formats.some(ft => dir.endsWith(ft)))\n    .map(dir => dir.replace(\u002F\\.[^\u002F.]+$\u002F, \"\"));\n\n\u002F\u002F https:\u002F\u002Fv3.nuxtjs.org\u002Fapi\u002Fconfiguration\u002Fnuxt.config\nexport default defineNuxtConfig({\n    nitro: {\n        prerender: {      \n            routes: [...contentFiles]\n        },\n    }\n}\n",[17,587,588,600,604,628,632,636,662,686,697,725,761,805,809,813,824,831,838,850,855,860],{"__ignoreMap":42},[46,589,590,592,594,596,598],{"class":48,"line":49},[46,591,170],{"class":59},[46,593,173],{"class":77},[46,595,176],{"class":59},[46,597,179],{"class":102},[46,599,182],{"class":70},[46,601,602],{"class":48,"line":56},[46,603,188],{"emptyLinePlaceholder":187},[46,605,606,608,610,612,614,616,618,620,622,624,626],{"class":48,"line":74},[46,607,193],{"class":59},[46,609,197],{"class":196},[46,611,201],{"class":200},[46,613,173],{"class":196},[46,615,206],{"class":70},[46,617,209],{"class":66},[46,619,212],{"class":70},[46,621,215],{"class":102},[46,623,218],{"class":200},[46,625,221],{"class":102},[46,627,224],{"class":70},[46,629,630],{"class":48,"line":84},[46,631,188],{"emptyLinePlaceholder":187},[46,633,634],{"class":48,"line":93},[46,635,355],{"class":52},[46,637,638,640,642,644,646,648,650,652,654,656,658,660],{"class":48,"line":115},[46,639,193],{"class":59},[46,641,362],{"class":196},[46,643,201],{"class":200},[46,645,367],{"class":70},[46,647,370],{"class":102},[46,649,106],{"class":70},[46,651,375],{"class":102},[46,653,106],{"class":70},[46,655,380],{"class":102},[46,657,106],{"class":70},[46,659,385],{"class":102},[46,661,293],{"class":70},[46,663,664,666,668,670,672,674,676,678,680,682,684],{"class":48,"line":121},[46,665,193],{"class":59},[46,667,197],{"class":196},[46,669,201],{"class":200},[46,671,173],{"class":196},[46,673,206],{"class":70},[46,675,209],{"class":66},[46,677,212],{"class":70},[46,679,215],{"class":102},[46,681,218],{"class":200},[46,683,221],{"class":102},[46,685,224],{"class":70},[46,687,688,690,693,695],{"class":48,"line":127},[46,689,193],{"class":59},[46,691,692],{"class":196}," contentFiles",[46,694,201],{"class":200},[46,696,425],{"class":77},[46,698,699,701,703,705,707,709,711,713,715,717,719,721,723],{"class":48,"line":268},[46,700,430],{"class":70},[46,702,433],{"class":66},[46,704,212],{"class":70},[46,706,439],{"class":438},[46,708,442],{"class":59},[46,710,445],{"class":196},[46,712,206],{"class":70},[46,714,450],{"class":66},[46,716,212],{"class":70},[46,718,215],{"class":102},[46,720,106],{"class":70},[46,722,459],{"class":102},[46,724,462],{"class":70},[46,726,727,729,731,733,735,737,739,741,743,745,747,749,751,753,755,757,759],{"class":48,"line":275},[46,728,430],{"class":70},[46,730,469],{"class":66},[46,732,212],{"class":70},[46,734,439],{"class":438},[46,736,442],{"class":59},[46,738,362],{"class":196},[46,740,206],{"class":70},[46,742,482],{"class":66},[46,744,212],{"class":70},[46,746,487],{"class":438},[46,748,442],{"class":59},[46,750,445],{"class":196},[46,752,206],{"class":70},[46,754,496],{"class":66},[46,756,212],{"class":70},[46,758,487],{"class":77},[46,760,503],{"class":70},[46,762,763,765,767,769,771,773,775,777,779,781,783,785,787,789,791,793,795,797,799,801,803],{"class":48,"line":296},[46,764,430],{"class":70},[46,766,433],{"class":66},[46,768,212],{"class":70},[46,770,439],{"class":438},[46,772,442],{"class":59},[46,774,445],{"class":196},[46,776,206],{"class":70},[46,778,450],{"class":66},[46,780,212],{"class":70},[46,782,526],{"class":77},[46,784,529],{"class":200},[46,786,533],{"class":532},[46,788,536],{"class":70},[46,790,526],{"class":532},[46,792,206],{"class":77},[46,794,543],{"class":532},[46,796,546],{"class":59},[46,798,526],{"class":77},[46,800,106],{"class":70},[46,802,553],{"class":102},[46,804,556],{"class":70},[46,806,807],{"class":48,"line":301},[46,808,188],{"emptyLinePlaceholder":187},[46,810,811],{"class":48,"line":306},[46,812,53],{"class":52},[46,814,816,818,820,822],{"class":48,"line":815},14,[46,817,60],{"class":59},[46,819,63],{"class":59},[46,821,67],{"class":66},[46,823,71],{"class":70},[46,825,827,829],{"class":48,"line":826},15,[46,828,78],{"class":77},[46,830,81],{"class":70},[46,832,834,836],{"class":48,"line":833},16,[46,835,87],{"class":77},[46,837,90],{"class":70},[46,839,841,843,846,848],{"class":48,"line":840},17,[46,842,96],{"class":77},[46,844,845],{"class":70},": [...",[46,847,420],{"class":77},[46,849,293],{"class":70},[46,851,853],{"class":48,"line":852},18,[46,854,118],{"class":70},[46,856,858],{"class":48,"line":857},19,[46,859,124],{"class":70},[46,861,863],{"class":48,"line":862},20,[46,864,130],{"class":70},[13,866,867,868,870],{},"Tada! Each supported file in the ",[17,869,314],{}," directory should now be discoverable.",[872,873,874],"style",{},"html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}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 pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .s_ZVi, html code.shiki .s_ZVi{--shiki-default:#E06C75;--shiki-default-font-style:italic}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}",{"title":42,"searchDepth":74,"depth":74,"links":876},[877],{"id":137,"depth":56,"text":138},1663771293000,"A guide prerendering all routes located in the content folder for @nuxt\u002Fcontent","md",{},"\u002Fblog\u002Fprerendering-all-routes-by-default-with-nuxt-content",null,{"title":5,"description":879},"g54j",{"loc":882},"blog\u002Fprerendering-all-routes-by-default-with-nuxt-content","89GEilh-_lsnTiCDIWMdHhtxUYSYddUWZ-x8DEy_WuM",{"type":890,"name":891,"children":892,"paging":893},"feed","Webmentions",[],{"per-page":862,"page":894,"total":894,"total-pages":894},0,1792202290060]