[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"roadmap-learn-strapi-5-from-scratch-for-modern-content-platforms-es":3},{"data":4,"meta":1980},[5],{"id":6,"documentId":7,"title":8,"slug":9,"excerpt":10,"level":11,"durationEstimate":12,"body":13,"createdAt":1689,"updatedAt":1689,"publishedAt":1690,"coverImage":1691,"author":1737,"relatedStacks":1745},21,"r18np8vppa0aj1v0pseemiu6","Learn Strapi 5 from Scratch for Modern Content Platforms","learn-strapi-5-from-scratch-for-modern-content-platforms","A practical beginner roadmap to learn Strapi 5 from scratch by building a real blog CMS with content types, components, schema thinking, REST APIs, custom routes, and frontend-ready content delivery.","beginner","3 to 5 weeks",[14,20,24,28,32,36,40,44,48,52,56,60,63,67,71,75,79,83,87,91,94,98,101,105,108,112,115,119,123,127,131,135,139,142,146,150,154,158,162,165,169,172,176,180,184,188,192,196,199,203,207,210,214,218,221,225,229,233,237,241,245,248,252,255,258,262,265,269,272,276,280,284,287,291,294,298,302,306,310,314,318,322,326,330,333,337,340,344,348,352,356,360,363,367,371,374,378,382,386,390,394,398,402,406,410,414,418,422,425,429,433,437,441,445,449,453,457,460,463,467,471,474,478,482,485,489,493,497,501,504,508,512,516,519,523,527,531,535,539,542,546,549,553,557,560,564,568,572,576,580,584,588,591,594,598,601,604,608,611,615,618,621,625,629,632,636,639,642,646,649,652,655,658,661,664,667,671,674,678,682,686,690,694,698,701,705,709,713,717,721,725,729,732,736,740,744,748,752,756,759,763,767,770,774,778,782,786,790,794,798,801,805,809,812,816,819,822,826,829,833,836,839,843,846,850,853,856,859,863,867,871,875,879,883,886,890,894,897,901,905,909,912,916,920,923,927,931,934,937,941,945,948,951,955,959,963,966,969,973,976,979,982,986,990,994,998,1002,1006,1010,1014,1017,1021,1024,1027,1031,1034,1037,1041,1044,1047,1051,1054,1057,1061,1065,1069,1073,1076,1080,1084,1087,1091,1095,1099,1103,1107,1111,1115,1119,1123,1127,1131,1135,1139,1143,1147,1151,1155,1159,1163,1167,1171,1175,1178,1182,1185,1189,1193,1196,1200,1203,1207,1211,1214,1218,1221,1224,1228,1232,1236,1240,1244,1248,1252,1256,1260,1264,1268,1272,1275,1279,1283,1286,1289,1293,1297,1300,1303,1307,1311,1315,1319,1323,1327,1331,1335,1339,1342,1346,1350,1354,1357,1360,1363,1366,1369,1373,1377,1381,1385,1389,1392,1396,1400,1403,1407,1410,1414,1418,1422,1426,1430,1433,1436,1440,1444,1447,1451,1455,1458,1462,1465,1469,1473,1477,1481,1485,1489,1493,1497,1500,1503,1506,1510,1514,1518,1521,1524,1528,1532,1536,1539,1543,1547,1550,1554,1558,1562,1566,1570,1574,1577,1581,1585,1588,1592,1596,1600,1604,1608,1612,1615,1619,1623,1627,1631,1635,1639,1643,1647,1651,1655,1658,1662,1665,1669,1673,1677,1681,1685],{"type":15,"children":16},"paragraph",[17],{"text":18,"type":19},"## What the beginner will build","text",{"type":15,"children":21},[22],{"text":23,"type":19},"A simple blog CMS with:",{"type":15,"children":25},[26],{"text":27,"type":19},"* Authors",{"type":15,"children":29},[30],{"text":31,"type":19},"* Categories",{"type":15,"children":33},[34],{"text":35,"type":19},"* Posts",{"type":15,"children":37},[38],{"text":39,"type":19},"* A reusable SEO component",{"type":15,"children":41},[42],{"text":43,"type":19},"* Public REST API endpoints",{"type":15,"children":45},[46],{"text":47,"type":19},"* A custom `featured posts` endpoint",{"type":15,"children":49},[50],{"text":51,"type":19},"* A frontend-ready content structure",{"type":15,"children":53},[54],{"text":55,"type":19},"",{"type":15,"children":57},[58],{"text":59,"type":19},"This is the right first project because it teaches the core Strapi mental model: **model content, manage entries, expose APIs, then extend when needed**. Strapi’s docs describe this exact pattern: define content-types with the Content-type Builder, manage entries through the admin, and access them through generated APIs. ([Strapi Docs][2])",{"type":15,"children":61},[62],{"text":55,"type":19},{"type":15,"children":64},[65],{"text":66,"type":19},"## Stage 1 — Install Strapi 5 and run it locally",{"type":15,"children":68},[69],{"text":70,"type":19},"Start with the official project creation flow:",{"type":15,"children":72},[73],{"text":74,"type":19},"```bash",{"type":15,"children":76},[77],{"text":78,"type":19},"npx create-strapi@latest my-strapi-blog",{"type":15,"children":80},[81],{"text":82,"type":19},"cd my-strapi-blog",{"type":15,"children":84},[85],{"text":86,"type":19},"npm run develop",{"type":15,"children":88},[89],{"text":90,"type":19},"```",{"type":15,"children":92},[93],{"text":55,"type":19},{"type":15,"children":95},[96],{"text":97,"type":19},"Then open:",{"type":15,"children":99},[100],{"text":74,"type":19},{"type":15,"children":102},[103],{"text":104,"type":19},"http://localhost:1337/admin",{"type":15,"children":106},[107],{"text":90,"type":19},{"type":15,"children":109},[110],{"text":111,"type":19},"The official quick start guide uses `create-strapi@latest`, then starts development with `npm run develop`. It also notes that the first run takes you into the admin setup flow. ([Strapi Docs][1])",{"type":15,"children":113},[114],{"text":55,"type":19},{"type":15,"children":116},[117],{"text":118,"type":19},"### What the beginner should learn here",{"type":15,"children":120},[121],{"text":122,"type":19},"* What Strapi is",{"type":15,"children":124},[125],{"text":126,"type":19},"* What a headless CMS is",{"type":15,"children":128},[129],{"text":130,"type":19},"* Why Strapi is not the frontend",{"type":15,"children":132},[133],{"text":134,"type":19},"* What the admin panel is for",{"type":15,"children":136},[137],{"text":138,"type":19},"At this point, the beginner should understand one key truth: **Strapi is the content engine, not the website itself**. That mindset is the difference between learning cleanly and getting lost in the sauce.",{"type":15,"children":140},[141],{"text":55,"type":19},{"type":15,"children":143},[144],{"text":145,"type":19},"## Stage 2 — Learn the content model basics",{"type":15,"children":147},[148],{"text":149,"type":19},"Strapi’s Content-type Builder lets you create:",{"type":15,"children":151},[152],{"text":153,"type":19},"* **Collection types** for multiple entries",{"type":15,"children":155},[156],{"text":157,"type":19},"* **Single types** for one-off content",{"type":15,"children":159},[160],{"text":161,"type":19},"* **Components** for reusable structured fields",{"type":15,"children":163},[164],{"text":55,"type":19},{"type":15,"children":166},[167],{"text":168,"type":19},"It is also only available in the development environment, which matters when teaching beginners how schema design works. ([Strapi Docs][2])",{"type":15,"children":170},[171],{"text":55,"type":19},{"type":15,"children":173},[174],{"text":175,"type":19},"### Beginner mental model",{"type":15,"children":177},[178],{"text":179,"type":19},"* `Post` → collection type",{"type":15,"children":181},[182],{"text":183,"type":19},"* `Author` → collection type",{"type":15,"children":185},[186],{"text":187,"type":19},"* `Category` → collection type",{"type":15,"children":189},[190],{"text":191,"type":19},"* `Homepage` → single type",{"type":15,"children":193},[194],{"text":195,"type":19},"* `SEO` → component",{"type":15,"children":197},[198],{"text":55,"type":19},{"type":15,"children":200},[201],{"text":202,"type":19},"### Why this matters",{"type":15,"children":204},[205],{"text":206,"type":19},"A beginner should stop thinking in pages only and start thinking in **structured content blocks**. That shift is the whole game.",{"type":15,"children":208},[209],{"text":55,"type":19},{"type":15,"children":211},[212],{"text":213,"type":19},"## Stage 3 — Create the first real content model",{"type":15,"children":215},[216],{"text":217,"type":19},"Build these in the Strapi admin.",{"type":15,"children":219},[220],{"text":55,"type":19},{"type":15,"children":222},[223],{"text":224,"type":19},"### Collection Type: Author",{"type":15,"children":226},[227],{"text":228,"type":19},"Fields:",{"type":15,"children":230},[231],{"text":232,"type":19},"* `name` → Text, required",{"type":15,"children":234},[235],{"text":236,"type":19},"* `email` → Email",{"type":15,"children":238},[239],{"text":240,"type":19},"* `bio` → Rich text",{"type":15,"children":242},[243],{"text":244,"type":19},"* `avatar` → Media, single image",{"type":15,"children":246},[247],{"text":55,"type":19},{"type":15,"children":249},[250],{"text":251,"type":19},"### Collection Type: Category",{"type":15,"children":253},[254],{"text":228,"type":19},{"type":15,"children":256},[257],{"text":232,"type":19},{"type":15,"children":259},[260],{"text":261,"type":19},"* `slug` → UID based on `name`",{"type":15,"children":263},[264],{"text":55,"type":19},{"type":15,"children":266},[267],{"text":268,"type":19},"### Component: SEO",{"type":15,"children":270},[271],{"text":228,"type":19},{"type":15,"children":273},[274],{"text":275,"type":19},"* `metaTitle` → Text",{"type":15,"children":277},[278],{"text":279,"type":19},"* `metaDescription` → Text",{"type":15,"children":281},[282],{"text":283,"type":19},"* `ogImage` → Media, single image",{"type":15,"children":285},[286],{"text":55,"type":19},{"type":15,"children":288},[289],{"text":290,"type":19},"### Collection Type: Post",{"type":15,"children":292},[293],{"text":228,"type":19},{"type":15,"children":295},[296],{"text":297,"type":19},"* `title` → Text, required",{"type":15,"children":299},[300],{"text":301,"type":19},"* `slug` → UID based on `title`",{"type":15,"children":303},[304],{"text":305,"type":19},"* `excerpt` → Text",{"type":15,"children":307},[308],{"text":309,"type":19},"* `content` → Blocks / rich content",{"type":15,"children":311},[312],{"text":313,"type":19},"* `cover` → Media",{"type":15,"children":315},[316],{"text":317,"type":19},"* `featured` → Boolean",{"type":15,"children":319},[320],{"text":321,"type":19},"* `author` → Relation, many posts to one author",{"type":15,"children":323},[324],{"text":325,"type":19},"* `categories` → Relation, many posts to many categories",{"type":15,"children":327},[328],{"text":329,"type":19},"* `seo` → Component, single `SEO`",{"type":15,"children":331},[332],{"text":55,"type":19},{"type":15,"children":334},[335],{"text":336,"type":19},"The official builder docs confirm support for collection types, components, field configuration, relations, and advanced options such as Draft & Publish. They also note that a content-type is only truly created once it is saved and has at least one valid field. ([Strapi Docs][2])",{"type":15,"children":338},[339],{"text":55,"type":19},{"type":15,"children":341},[342],{"text":343,"type":19},"### What the beginner learns here",{"type":15,"children":345},[346],{"text":347,"type":19},"* How content-types differ from components",{"type":15,"children":349},[350],{"text":351,"type":19},"* Why relations matter",{"type":15,"children":353},[354],{"text":355,"type":19},"* Why UID fields are perfect for slugs",{"type":15,"children":357},[358],{"text":359,"type":19},"* How reusable SEO structures save pain later",{"type":15,"children":361},[362],{"text":55,"type":19},{"type":15,"children":364},[365],{"text":366,"type":19},"## Stage 4 — Show the beginner what the schema looks like",{"type":15,"children":368},[369],{"text":370,"type":19},"Even if the beginner builds through the UI first, they should still see the file-level structure. That removes the magic trick feeling.",{"type":15,"children":372},[373],{"text":55,"type":19},{"type":15,"children":375},[376],{"text":377,"type":19},"### Example `src/api/post/content-types/post/schema.json`",{"type":15,"children":379},[380],{"text":381,"type":19},"```json",{"type":15,"children":383},[384],{"text":385,"type":19},"{",{"type":15,"children":387},[388],{"text":389,"type":19},"  \"kind\": \"collectionType\",",{"type":15,"children":391},[392],{"text":393,"type":19},"  \"collectionName\": \"posts\",",{"type":15,"children":395},[396],{"text":397,"type":19},"  \"info\": {",{"type":15,"children":399},[400],{"text":401,"type":19},"    \"singularName\": \"post\",",{"type":15,"children":403},[404],{"text":405,"type":19},"    \"pluralName\": \"posts\",",{"type":15,"children":407},[408],{"text":409,"type":19},"    \"displayName\": \"Post\"",{"type":15,"children":411},[412],{"text":413,"type":19},"  },",{"type":15,"children":415},[416],{"text":417,"type":19},"  \"options\": {",{"type":15,"children":419},[420],{"text":421,"type":19},"    \"draftAndPublish\": true",{"type":15,"children":423},[424],{"text":413,"type":19},{"type":15,"children":426},[427],{"text":428,"type":19},"  \"attributes\": {",{"type":15,"children":430},[431],{"text":432,"type":19},"    \"title\": {",{"type":15,"children":434},[435],{"text":436,"type":19},"      \"type\": \"string\",",{"type":15,"children":438},[439],{"text":440,"type":19},"      \"required\": true",{"type":15,"children":442},[443],{"text":444,"type":19},"    },",{"type":15,"children":446},[447],{"text":448,"type":19},"    \"slug\": {",{"type":15,"children":450},[451],{"text":452,"type":19},"      \"type\": \"uid\",",{"type":15,"children":454},[455],{"text":456,"type":19},"      \"targetField\": \"title\",",{"type":15,"children":458},[459],{"text":440,"type":19},{"type":15,"children":461},[462],{"text":444,"type":19},{"type":15,"children":464},[465],{"text":466,"type":19},"    \"excerpt\": {",{"type":15,"children":468},[469],{"text":470,"type":19},"      \"type\": \"text\"",{"type":15,"children":472},[473],{"text":444,"type":19},{"type":15,"children":475},[476],{"text":477,"type":19},"    \"content\": {",{"type":15,"children":479},[480],{"text":481,"type":19},"      \"type\": \"blocks\"",{"type":15,"children":483},[484],{"text":444,"type":19},{"type":15,"children":486},[487],{"text":488,"type":19},"    \"cover\": {",{"type":15,"children":490},[491],{"text":492,"type":19},"      \"type\": \"media\",",{"type":15,"children":494},[495],{"text":496,"type":19},"      \"multiple\": false,",{"type":15,"children":498},[499],{"text":500,"type":19},"      \"allowedTypes\": [\"images\"]",{"type":15,"children":502},[503],{"text":444,"type":19},{"type":15,"children":505},[506],{"text":507,"type":19},"    \"featured\": {",{"type":15,"children":509},[510],{"text":511,"type":19},"      \"type\": \"boolean\",",{"type":15,"children":513},[514],{"text":515,"type":19},"      \"default\": false",{"type":15,"children":517},[518],{"text":444,"type":19},{"type":15,"children":520},[521],{"text":522,"type":19},"    \"author\": {",{"type":15,"children":524},[525],{"text":526,"type":19},"      \"type\": \"relation\",",{"type":15,"children":528},[529],{"text":530,"type":19},"      \"relation\": \"manyToOne\",",{"type":15,"children":532},[533],{"text":534,"type":19},"      \"target\": \"api::author.author\",",{"type":15,"children":536},[537],{"text":538,"type":19},"      \"inversedBy\": \"posts\"",{"type":15,"children":540},[541],{"text":444,"type":19},{"type":15,"children":543},[544],{"text":545,"type":19},"    \"categories\": {",{"type":15,"children":547},[548],{"text":526,"type":19},{"type":15,"children":550},[551],{"text":552,"type":19},"      \"relation\": \"manyToMany\",",{"type":15,"children":554},[555],{"text":556,"type":19},"      \"target\": \"api::category.category\"",{"type":15,"children":558},[559],{"text":444,"type":19},{"type":15,"children":561},[562],{"text":563,"type":19},"    \"seo\": {",{"type":15,"children":565},[566],{"text":567,"type":19},"      \"type\": \"component\",",{"type":15,"children":569},[570],{"text":571,"type":19},"      \"repeatable\": false,",{"type":15,"children":573},[574],{"text":575,"type":19},"      \"component\": \"shared.seo\"",{"type":15,"children":577},[578],{"text":579,"type":19},"    }",{"type":15,"children":581},[582],{"text":583,"type":19},"  }",{"type":15,"children":585},[586],{"text":587,"type":19},"}",{"type":15,"children":589},[590],{"text":90,"type":19},{"type":15,"children":592},[593],{"text":55,"type":19},{"type":15,"children":595},[596],{"text":597,"type":19},"### Example `src/components/shared/seo.json`",{"type":15,"children":599},[600],{"text":381,"type":19},{"type":15,"children":602},[603],{"text":385,"type":19},{"type":15,"children":605},[606],{"text":607,"type":19},"  \"collectionName\": \"components_shared_seos\",",{"type":15,"children":609},[610],{"text":397,"type":19},{"type":15,"children":612},[613],{"text":614,"type":19},"    \"displayName\": \"SEO\"",{"type":15,"children":616},[617],{"text":413,"type":19},{"type":15,"children":619},[620],{"text":428,"type":19},{"type":15,"children":622},[623],{"text":624,"type":19},"    \"metaTitle\": {",{"type":15,"children":626},[627],{"text":628,"type":19},"      \"type\": \"string\"",{"type":15,"children":630},[631],{"text":444,"type":19},{"type":15,"children":633},[634],{"text":635,"type":19},"    \"metaDescription\": {",{"type":15,"children":637},[638],{"text":470,"type":19},{"type":15,"children":640},[641],{"text":444,"type":19},{"type":15,"children":643},[644],{"text":645,"type":19},"    \"ogImage\": {",{"type":15,"children":647},[648],{"text":492,"type":19},{"type":15,"children":650},[651],{"text":496,"type":19},{"type":15,"children":653},[654],{"text":500,"type":19},{"type":15,"children":656},[657],{"text":579,"type":19},{"type":15,"children":659},[660],{"text":583,"type":19},{"type":15,"children":662},[663],{"text":587,"type":19},{"type":15,"children":665},[666],{"text":90,"type":19},{"type":15,"children":668},[669],{"text":670,"type":19},"The builder docs explicitly describe content-types, fields, relations, components, and advanced settings like Draft & Publish, which is why showing the generated schema shape is a strong teaching move. ([Strapi Docs][2])",{"type":15,"children":672},[673],{"text":55,"type":19},{"type":15,"children":675},[676],{"text":677,"type":19},"### Beginner takeaway",{"type":15,"children":679},[680],{"text":681,"type":19},"* `kind: collectionType` means many entries",{"type":15,"children":683},[684],{"text":685,"type":19},"* `uid` is great for slugs",{"type":15,"children":687},[688],{"text":689,"type":19},"* `relation` connects content",{"type":15,"children":691},[692],{"text":693,"type":19},"* `component` makes structures reusable",{"type":15,"children":695},[696],{"text":697,"type":19},"* `draftAndPublish` enables editorial workflow",{"type":15,"children":699},[700],{"text":55,"type":19},{"type":15,"children":702},[703],{"text":704,"type":19},"## Stage 5 — Add real content through Content Manager",{"type":15,"children":706},[707],{"text":708,"type":19},"Now create actual entries:",{"type":15,"children":710},[711],{"text":712,"type":19},"* 1 author",{"type":15,"children":714},[715],{"text":716,"type":19},"* 2 categories",{"type":15,"children":718},[719],{"text":720,"type":19},"* 3 posts",{"type":15,"children":722},[723],{"text":724,"type":19},"* mark 1 post as `featured`",{"type":15,"children":726},[727],{"text":728,"type":19},"The quick start guide follows this same rhythm: create structure first, then create content entries. ([Strapi Docs][1])",{"type":15,"children":730},[731],{"text":55,"type":19},{"type":15,"children":733},[734],{"text":735,"type":19},"### What the beginner learns",{"type":15,"children":737},[738],{"text":739,"type":19},"* How to save drafts",{"type":15,"children":741},[742],{"text":743,"type":19},"* How publishing works",{"type":15,"children":745},[746],{"text":747,"type":19},"* How relations appear in actual entries",{"type":15,"children":749},[750],{"text":751,"type":19},"* Why clean sample data matters for testing APIs",{"type":15,"children":753},[754],{"text":755,"type":19},"A CMS without data is just a fancy skeleton wearing a blazer.",{"type":15,"children":757},[758],{"text":55,"type":19},{"type":15,"children":760},[761],{"text":762,"type":19},"## Stage 6 — Learn the REST API",{"type":15,"children":764},[765],{"text":766,"type":19},"Strapi auto-generates REST endpoints for content-types. The REST API docs also note that relations, media, components, and dynamic zones are **not returned by default** unless you use `populate`. ([Strapi Docs][3])",{"type":15,"children":768},[769],{"text":55,"type":19},{"type":15,"children":771},[772],{"text":773,"type":19},"### First, enable public permissions",{"type":15,"children":775},[776],{"text":777,"type":19},"In the admin:",{"type":15,"children":779},[780],{"text":781,"type":19},"* Settings",{"type":15,"children":783},[784],{"text":785,"type":19},"* Users & Permissions",{"type":15,"children":787},[788],{"text":789,"type":19},"* Roles",{"type":15,"children":791},[792],{"text":793,"type":19},"* Public",{"type":15,"children":795},[796],{"text":797,"type":19},"* Enable `find` and `findOne` for `post`, `author`, and `category`",{"type":15,"children":799},[800],{"text":55,"type":19},{"type":15,"children":802},[803],{"text":804,"type":19},"### Test the endpoints",{"type":15,"children":806},[807],{"text":808,"type":19},"#### Get all posts",{"type":15,"children":810},[811],{"text":74,"type":19},{"type":15,"children":813},[814],{"text":815,"type":19},"curl http://localhost:1337/api/posts",{"type":15,"children":817},[818],{"text":90,"type":19},{"type":15,"children":820},[821],{"text":55,"type":19},{"type":15,"children":823},[824],{"text":825,"type":19},"#### Get posts with everything populated",{"type":15,"children":827},[828],{"text":74,"type":19},{"type":15,"children":830},[831],{"text":832,"type":19},"curl \"http://localhost:1337/api/posts?populate=*\"",{"type":15,"children":834},[835],{"text":90,"type":19},{"type":15,"children":837},[838],{"text":55,"type":19},{"type":15,"children":840},[841],{"text":842,"type":19},"#### Get one post by slug",{"type":15,"children":844},[845],{"text":74,"type":19},{"type":15,"children":847},[848],{"text":849,"type":19},"curl \"http://localhost:1337/api/posts?filters[slug][$eq]=my-first-post&populate=*\"",{"type":15,"children":851},[852],{"text":90,"type":19},{"type":15,"children":854},[855],{"text":55,"type":19},{"type":15,"children":857},[858],{"text":343,"type":19},{"type":15,"children":860},[861],{"text":862,"type":19},"* Base endpoint pattern",{"type":15,"children":864},[865],{"text":866,"type":19},"* `populate=*`",{"type":15,"children":868},[869],{"text":870,"type":19},"* Filters",{"type":15,"children":872},[873],{"text":874,"type":19},"* Public permissions",{"type":15,"children":876},[877],{"text":878,"type":19},"* Why APIs are private until you open them intentionally",{"type":15,"children":880},[881],{"text":882,"type":19},"That last one matters. Production is not a playground.",{"type":15,"children":884},[885],{"text":55,"type":19},{"type":15,"children":887},[888],{"text":889,"type":19},"## Stage 7 — Fetch Strapi data from JavaScript",{"type":15,"children":891},[892],{"text":893,"type":19},"A beginner should see Strapi from the frontend side early.",{"type":15,"children":895},[896],{"text":55,"type":19},{"type":15,"children":898},[899],{"text":900,"type":19},"### Fetch all posts",{"type":15,"children":902},[903],{"text":904,"type":19},"```js",{"type":15,"children":906},[907],{"text":908,"type":19},"const STRAPI_URL = \"http://localhost:1337\";",{"type":15,"children":910},[911],{"text":55,"type":19},{"type":15,"children":913},[914],{"text":915,"type":19},"async function getPosts() {",{"type":15,"children":917},[918],{"text":919,"type":19},"  const res = await fetch(`${STRAPI_URL}/api/posts?populate=*`);",{"type":15,"children":921},[922],{"text":55,"type":19},{"type":15,"children":924},[925],{"text":926,"type":19},"  if (!res.ok) {",{"type":15,"children":928},[929],{"text":930,"type":19},"    throw new Error(\"Failed to fetch posts\");",{"type":15,"children":932},[933],{"text":583,"type":19},{"type":15,"children":935},[936],{"text":55,"type":19},{"type":15,"children":938},[939],{"text":940,"type":19},"  const data = await res.json();",{"type":15,"children":942},[943],{"text":944,"type":19},"  return data;",{"type":15,"children":946},[947],{"text":587,"type":19},{"type":15,"children":949},[950],{"text":55,"type":19},{"type":15,"children":952},[953],{"text":954,"type":19},"getPosts()",{"type":15,"children":956},[957],{"text":958,"type":19},"  .then((data) => console.log(data))",{"type":15,"children":960},[961],{"text":962,"type":19},"  .catch((error) => console.error(error));",{"type":15,"children":964},[965],{"text":90,"type":19},{"type":15,"children":967},[968],{"text":55,"type":19},{"type":15,"children":970},[971],{"text":972,"type":19},"### Fetch a single post by slug",{"type":15,"children":974},[975],{"text":904,"type":19},{"type":15,"children":977},[978],{"text":908,"type":19},{"type":15,"children":980},[981],{"text":55,"type":19},{"type":15,"children":983},[984],{"text":985,"type":19},"async function getPostBySlug(slug) {",{"type":15,"children":987},[988],{"text":989,"type":19},"  const query = new URLSearchParams({",{"type":15,"children":991},[992],{"text":993,"type":19},"    \"filters[slug][$eq]\": slug,",{"type":15,"children":995},[996],{"text":997,"type":19},"    \"populate[cover]\": \"*\",",{"type":15,"children":999},[1000],{"text":1001,"type":19},"    \"populate[author][populate]\": \"*\",",{"type":15,"children":1003},[1004],{"text":1005,"type":19},"    \"populate[categories]\": \"*\",",{"type":15,"children":1007},[1008],{"text":1009,"type":19},"    \"populate[seo][populate]\": \"*\"",{"type":15,"children":1011},[1012],{"text":1013,"type":19},"  });",{"type":15,"children":1015},[1016],{"text":55,"type":19},{"type":15,"children":1018},[1019],{"text":1020,"type":19},"  const res = await fetch(`${STRAPI_URL}/api/posts?${query.toString()}`);",{"type":15,"children":1022},[1023],{"text":55,"type":19},{"type":15,"children":1025},[1026],{"text":926,"type":19},{"type":15,"children":1028},[1029],{"text":1030,"type":19},"    throw new Error(\"Failed to fetch post\");",{"type":15,"children":1032},[1033],{"text":583,"type":19},{"type":15,"children":1035},[1036],{"text":55,"type":19},{"type":15,"children":1038},[1039],{"text":1040,"type":19},"  return res.json();",{"type":15,"children":1042},[1043],{"text":587,"type":19},{"type":15,"children":1045},[1046],{"text":90,"type":19},{"type":15,"children":1048},[1049],{"text":1050,"type":19},"The REST docs support this query-based style for filtering and population. ([Strapi Docs][4])",{"type":15,"children":1052},[1053],{"text":55,"type":19},{"type":15,"children":1055},[1056],{"text":735,"type":19},{"type":15,"children":1058},[1059],{"text":1060,"type":19},"* How a frontend consumes Strapi",{"type":15,"children":1062},[1063],{"text":1064,"type":19},"* Why populate matters",{"type":15,"children":1066},[1067],{"text":1068,"type":19},"* Why slugs are useful",{"type":15,"children":1070},[1071],{"text":1072,"type":19},"* How to shape data for blog pages",{"type":15,"children":1074},[1075],{"text":55,"type":19},{"type":15,"children":1077},[1078],{"text":1079,"type":19},"## Stage 8 — Show the project structure",{"type":15,"children":1081},[1082],{"text":1083,"type":19},"The beginner needs to understand where things live.",{"type":15,"children":1085},[1086],{"text":74,"type":19},{"type":15,"children":1088},[1089],{"text":1090,"type":19},"my-strapi-blog/",{"type":15,"children":1092},[1093],{"text":1094,"type":19},"├─ config/",{"type":15,"children":1096},[1097],{"text":1098,"type":19},"├─ database/",{"type":15,"children":1100},[1101],{"text":1102,"type":19},"├─ public/",{"type":15,"children":1104},[1105],{"text":1106,"type":19},"├─ src/",{"type":15,"children":1108},[1109],{"text":1110,"type":19},"│  ├─ api/",{"type":15,"children":1112},[1113],{"text":1114,"type":19},"│  │  ├─ author/",{"type":15,"children":1116},[1117],{"text":1118,"type":19},"│  │  │  ├─ content-types/",{"type":15,"children":1120},[1121],{"text":1122,"type":19},"│  │  │  │  └─ author/",{"type":15,"children":1124},[1125],{"text":1126,"type":19},"│  │  │  │     └─ schema.json",{"type":15,"children":1128},[1129],{"text":1130,"type":19},"│  │  │  ├─ controllers/",{"type":15,"children":1132},[1133],{"text":1134,"type":19},"│  │  │  ├─ routes/",{"type":15,"children":1136},[1137],{"text":1138,"type":19},"│  │  │  └─ services/",{"type":15,"children":1140},[1141],{"text":1142,"type":19},"│  │  ├─ category/",{"type":15,"children":1144},[1145],{"text":1146,"type":19},"│  │  └─ post/",{"type":15,"children":1148},[1149],{"text":1150,"type":19},"│  ├─ components/",{"type":15,"children":1152},[1153],{"text":1154,"type":19},"│  │  └─ shared/",{"type":15,"children":1156},[1157],{"text":1158,"type":19},"│  │     └─ seo.json",{"type":15,"children":1160},[1161],{"text":1162,"type":19},"│  ├─ admin/",{"type":15,"children":1164},[1165],{"text":1166,"type":19},"│  └─ extensions/",{"type":15,"children":1168},[1169],{"text":1170,"type":19},"├─ package.json",{"type":15,"children":1172},[1173],{"text":1174,"type":19},"└─ .env",{"type":15,"children":1176},[1177],{"text":90,"type":19},{"type":15,"children":1179},[1180],{"text":1181,"type":19},"The backend customization docs describe Strapi’s flow through routes, controllers, middlewares, and services, which is why this structure matters for teaching real backend thinking. ([Strapi Docs][3])",{"type":15,"children":1183},[1184],{"text":55,"type":19},{"type":15,"children":1186},[1187],{"text":1188,"type":19},"## Stage 9 — Create a custom endpoint",{"type":15,"children":1190},[1191],{"text":1192,"type":19},"This is where the beginner stops treating Strapi like a magic content box and starts understanding it as a backend platform.",{"type":15,"children":1194},[1195],{"text":55,"type":19},{"type":15,"children":1197},[1198],{"text":1199,"type":19},"The official docs explain that routes map URLs to controllers and that controllers contain the logic executed for those routes. Strapi also auto-generates routes for content-types, but custom ones can be added. ([Strapi Docs][4])",{"type":15,"children":1201},[1202],{"text":55,"type":19},{"type":15,"children":1204},[1205],{"text":1206,"type":19},"### Goal",{"type":15,"children":1208},[1209],{"text":1210,"type":19},"Create:",{"type":15,"children":1212},[1213],{"text":74,"type":19},{"type":15,"children":1215},[1216],{"text":1217,"type":19},"GET /api/posts/featured",{"type":15,"children":1219},[1220],{"text":90,"type":19},{"type":15,"children":1222},[1223],{"text":55,"type":19},{"type":15,"children":1225},[1226],{"text":1227,"type":19},"### Route file",{"type":15,"children":1229},[1230],{"text":1231,"type":19},"#### `src/api/post/routes/custom-post.ts`",{"type":15,"children":1233},[1234],{"text":1235,"type":19},"```ts",{"type":15,"children":1237},[1238],{"text":1239,"type":19},"export default {",{"type":15,"children":1241},[1242],{"text":1243,"type":19},"  routes: [",{"type":15,"children":1245},[1246],{"text":1247,"type":19},"    {",{"type":15,"children":1249},[1250],{"text":1251,"type":19},"      method: \"GET\",",{"type":15,"children":1253},[1254],{"text":1255,"type":19},"      path: \"/posts/featured\",",{"type":15,"children":1257},[1258],{"text":1259,"type":19},"      handler: \"post.featured\",",{"type":15,"children":1261},[1262],{"text":1263,"type":19},"      config: {",{"type":15,"children":1265},[1266],{"text":1267,"type":19},"        auth: false",{"type":15,"children":1269},[1270],{"text":1271,"type":19},"      }",{"type":15,"children":1273},[1274],{"text":579,"type":19},{"type":15,"children":1276},[1277],{"text":1278,"type":19},"  ]",{"type":15,"children":1280},[1281],{"text":1282,"type":19},"};",{"type":15,"children":1284},[1285],{"text":90,"type":19},{"type":15,"children":1287},[1288],{"text":55,"type":19},{"type":15,"children":1290},[1291],{"text":1292,"type":19},"### Controller file",{"type":15,"children":1294},[1295],{"text":1296,"type":19},"#### `src/api/post/controllers/post.ts`",{"type":15,"children":1298},[1299],{"text":1235,"type":19},{"type":15,"children":1301},[1302],{"text":1239,"type":19},{"type":15,"children":1304},[1305],{"text":1306,"type":19},"  async featured(ctx) {",{"type":15,"children":1308},[1309],{"text":1310,"type":19},"    const entries = await strapi.documents(\"api::post.post\").findMany({",{"type":15,"children":1312},[1313],{"text":1314,"type":19},"      filters: {",{"type":15,"children":1316},[1317],{"text":1318,"type":19},"        featured: {",{"type":15,"children":1320},[1321],{"text":1322,"type":19},"          $eq: true",{"type":15,"children":1324},[1325],{"text":1326,"type":19},"        }",{"type":15,"children":1328},[1329],{"text":1330,"type":19},"      },",{"type":15,"children":1332},[1333],{"text":1334,"type":19},"      populate: [\"cover\", \"author\", \"categories\", \"seo\"]",{"type":15,"children":1336},[1337],{"text":1338,"type":19},"    });",{"type":15,"children":1340},[1341],{"text":55,"type":19},{"type":15,"children":1343},[1344],{"text":1345,"type":19},"    ctx.body = {",{"type":15,"children":1347},[1348],{"text":1349,"type":19},"      data: entries",{"type":15,"children":1351},[1352],{"text":1353,"type":19},"    };",{"type":15,"children":1355},[1356],{"text":583,"type":19},{"type":15,"children":1358},[1359],{"text":1282,"type":19},{"type":15,"children":1361},[1362],{"text":90,"type":19},{"type":15,"children":1364},[1365],{"text":55,"type":19},{"type":15,"children":1367},[1368],{"text":735,"type":19},{"type":15,"children":1370},[1371],{"text":1372,"type":19},"* What a route is",{"type":15,"children":1374},[1375],{"text":1376,"type":19},"* What a controller is",{"type":15,"children":1378},[1379],{"text":1380,"type":19},"* How to add custom backend logic",{"type":15,"children":1382},[1383],{"text":1384,"type":19},"* Why not every feature should rely on default CRUD only",{"type":15,"children":1386},[1387],{"text":1388,"type":19},"That is the first real backend flex.",{"type":15,"children":1390},[1391],{"text":55,"type":19},{"type":15,"children":1393},[1394],{"text":1395,"type":19},"## Stage 10 — Teach the CRUD map",{"type":15,"children":1397},[1398],{"text":1399,"type":19},"Strapi generates CRUD-style endpoints for content-types. The routes docs and backend docs confirm that these routes are auto-generated and can be extended. ([Strapi Docs][4])",{"type":15,"children":1401},[1402],{"text":55,"type":19},{"type":15,"children":1404},[1405],{"text":1406,"type":19},"### Mental CRUD map",{"type":15,"children":1408},[1409],{"text":74,"type":19},{"type":15,"children":1411},[1412],{"text":1413,"type":19},"GET /api/posts",{"type":15,"children":1415},[1416],{"text":1417,"type":19},"GET /api/posts/:id",{"type":15,"children":1419},[1420],{"text":1421,"type":19},"POST /api/posts",{"type":15,"children":1423},[1424],{"text":1425,"type":19},"PUT /api/posts/:id",{"type":15,"children":1427},[1428],{"text":1429,"type":19},"DELETE /api/posts/:id",{"type":15,"children":1431},[1432],{"text":90,"type":19},{"type":15,"children":1434},[1435],{"text":55,"type":19},{"type":15,"children":1437},[1438],{"text":1439,"type":19},"### Beginner lesson",{"type":15,"children":1441},[1442],{"text":1443,"type":19},"Even if the UI creates a lot for you, there is still a real backend pattern underneath. That matters because the beginner is not just learning a tool, but a backend way of thinking.",{"type":15,"children":1445},[1446],{"text":55,"type":19},{"type":15,"children":1448},[1449],{"text":1450,"type":19},"## Stage 11 — Connect to a real frontend",{"type":15,"children":1452},[1453],{"text":1454,"type":19},"A good beginner project should end with frontend consumption.",{"type":15,"children":1456},[1457],{"text":55,"type":19},{"type":15,"children":1459},[1460],{"text":1461,"type":19},"### Example rendering function",{"type":15,"children":1463},[1464],{"text":904,"type":19},{"type":15,"children":1466},[1467],{"text":1468,"type":19},"function renderPostCard(post) {",{"type":15,"children":1470},[1471],{"text":1472,"type":19},"  return `",{"type":15,"children":1474},[1475],{"text":1476,"type":19},"    \u003Carticle>",{"type":15,"children":1478},[1479],{"text":1480,"type":19},"      \u003Ch2>${post.title}\u003C/h2>",{"type":15,"children":1482},[1483],{"text":1484,"type":19},"      \u003Cp>${post.excerpt ?? \"\"}\u003C/p>",{"type":15,"children":1486},[1487],{"text":1488,"type":19},"      \u003Ca href=\"/blog/${post.slug}\">Read more\u003C/a>",{"type":15,"children":1490},[1491],{"text":1492,"type":19},"    \u003C/article>",{"type":15,"children":1494},[1495],{"text":1496,"type":19},"  `;",{"type":15,"children":1498},[1499],{"text":587,"type":19},{"type":15,"children":1501},[1502],{"text":90,"type":19},{"type":15,"children":1504},[1505],{"text":55,"type":19},{"type":15,"children":1507},[1508],{"text":1509,"type":19},"### Suggested beginner frontend routes",{"type":15,"children":1511},[1512],{"text":1513,"type":19},"* `/blog` → list all posts",{"type":15,"children":1515},[1516],{"text":1517,"type":19},"* `/blog/[slug]` → post detail page",{"type":15,"children":1519},[1520],{"text":55,"type":19},{"type":15,"children":1522},[1523],{"text":1439,"type":19},{"type":15,"children":1525},[1526],{"text":1527,"type":19},"Strapi handles content and API delivery.",{"type":15,"children":1529},[1530],{"text":1531,"type":19},"Your frontend handles presentation and user experience.",{"type":15,"children":1533},[1534],{"text":1535,"type":19},"Keep those roles clean and life gets less cursed.",{"type":15,"children":1537},[1538],{"text":55,"type":19},{"type":15,"children":1540},[1541],{"text":1542,"type":19},"## Stage 12 — Learn security basics",{"type":15,"children":1544},[1545],{"text":1546,"type":19},"The REST API is not public by default. Permissions must be configured intentionally. The REST docs and general backend flow reinforce that route access and API exposure should be controlled. ([Strapi Docs][4])",{"type":15,"children":1548},[1549],{"text":55,"type":19},{"type":15,"children":1551},[1552],{"text":1553,"type":19},"### Teach this clearly",{"type":15,"children":1555},[1556],{"text":1557,"type":19},"* Do not expose everything publicly",{"type":15,"children":1559},[1560],{"text":1561,"type":19},"* Use `find` and `findOne` only when appropriate",{"type":15,"children":1563},[1564],{"text":1565,"type":19},"* Keep drafts private",{"type":15,"children":1567},[1568],{"text":1569,"type":19},"* Do not confuse admin access with public API access",{"type":15,"children":1571},[1572],{"text":1573,"type":19},"This is a beginner lesson that saves future headaches.",{"type":15,"children":1575},[1576],{"text":55,"type":19},{"type":15,"children":1578},[1579],{"text":1580,"type":19},"## Stage 13 — Learn deployment basics",{"type":15,"children":1582},[1583],{"text":1584,"type":19},"The official deployment docs cover preparing Strapi for deployment and mention Strapi Cloud as one hosted option. They also note that Strapi’s data management system can help move structure and data between instances. ([Strapi Docs][5])",{"type":15,"children":1586},[1587],{"text":55,"type":19},{"type":15,"children":1589},[1590],{"text":1591,"type":19},"### Beginner deployment goals",{"type":15,"children":1593},[1594],{"text":1595,"type":19},"* Understand `.env`",{"type":15,"children":1597},[1598],{"text":1599,"type":19},"* Choose a production database",{"type":15,"children":1601},[1602],{"text":1603,"type":19},"* Think about media storage",{"type":15,"children":1605},[1606],{"text":1607,"type":19},"* Separate dev and production",{"type":15,"children":1609},[1610],{"text":1611,"type":19},"* Learn that localhost is not a business plan",{"type":15,"children":1613},[1614],{"text":55,"type":19},{"type":15,"children":1616},[1617],{"text":1618,"type":19},"## Recommended learning order",{"type":15,"children":1620},[1621],{"text":1622,"type":19},"1. Install Strapi 5",{"type":15,"children":1624},[1625],{"text":1626,"type":19},"2. Learn collection types, single types, and components",{"type":15,"children":1628},[1629],{"text":1630,"type":19},"3. Build `Author`, `Category`, `SEO`, and `Post`",{"type":15,"children":1632},[1633],{"text":1634,"type":19},"4. Add real content",{"type":15,"children":1636},[1637],{"text":1638,"type":19},"5. Open public API permissions safely",{"type":15,"children":1640},[1641],{"text":1642,"type":19},"6. Learn `populate` and filtering",{"type":15,"children":1644},[1645],{"text":1646,"type":19},"7. Consume data with JavaScript",{"type":15,"children":1648},[1649],{"text":1650,"type":19},"8. Add one custom route and controller",{"type":15,"children":1652},[1653],{"text":1654,"type":19},"9. Deploy the project",{"type":15,"children":1656},[1657],{"text":55,"type":19},{"type":15,"children":1659},[1660],{"text":1661,"type":19},"That order is clean. Starting with plugins or admin extensions on day one is just chaos in a suit.",{"type":15,"children":1663},[1664],{"text":55,"type":19},{"type":15,"children":1666},[1667],{"text":1668,"type":19},"[1]: https://docs.strapi.io/cms/quick-start \"Quick Start Guide - Strapi Developer Docs\"",{"type":15,"children":1670},[1671],{"text":1672,"type":19},"[2]: https://docs.strapi.io/cms/features/content-type-builder \"Content-type Builder | Strapi 5 Documentation\"",{"type":15,"children":1674},[1675],{"text":1676,"type":19},"[3]: https://docs.strapi.io/cms/backend-customization \"Back-end customization | Strapi 5 Documentation\"",{"type":15,"children":1678},[1679],{"text":1680,"type":19},"[4]: https://docs.strapi.io/cms/backend-customization/routes \"Routes | Strapi 5 Documentation\"",{"type":15,"children":1682},[1683],{"text":1684,"type":19},"[5]: https://docs.strapi.io/cms/deployment \"Deployment | Strapi 5 Documentation\"",{"type":15,"children":1686},[1687],{"text":1688,"type":19},"[6]: https://docs.strapi.io/cms/backend-customization/controllers \"Controllers | Strapi 5 Documentation\"","2026-03-14T03:22:07.510Z","2026-03-14T03:22:07.642Z",{"id":1692,"documentId":1693,"name":1694,"alternativeText":1695,"caption":1695,"focalPoint":1695,"width":1696,"height":1697,"formats":1698,"hash":1732,"ext":1700,"mime":1703,"size":1733,"url":1734,"previewUrl":1695,"provider":1735,"provider_metadata":1695,"createdAt":1736,"updatedAt":1736,"publishedAt":1736},12,"bu4061vdti1qaf996cxp874d","strapi-roadmap-from-scratch.png",null,1536,1024,{"large":1699,"small":1709,"medium":1717,"thumbnail":1724},{"ext":1700,"url":1701,"hash":1702,"mime":1703,"name":1704,"path":1695,"size":1705,"width":1706,"height":1707,"sizeInBytes":1708},".png","https://awesome-friends-6b6e40fa18.media.strapiapp.com/large_strapi_roadmap_from_scratch_c224fb6a01.png","large_strapi_roadmap_from_scratch_c224fb6a01","image/png","large_strapi-roadmap-from-scratch.png",1135.84,1000,667,1135840,{"ext":1700,"url":1710,"hash":1711,"mime":1703,"name":1712,"path":1695,"size":1713,"width":1714,"height":1715,"sizeInBytes":1716},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/small_strapi_roadmap_from_scratch_c224fb6a01.png","small_strapi_roadmap_from_scratch_c224fb6a01","small_strapi-roadmap-from-scratch.png",322.12,500,333,322121,{"ext":1700,"url":1718,"hash":1719,"mime":1703,"name":1720,"path":1695,"size":1721,"width":1722,"height":1714,"sizeInBytes":1723},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/medium_strapi_roadmap_from_scratch_c224fb6a01.png","medium_strapi_roadmap_from_scratch_c224fb6a01","medium_strapi-roadmap-from-scratch.png",670.11,750,670108,{"ext":1700,"url":1725,"hash":1726,"mime":1703,"name":1727,"path":1695,"size":1728,"width":1729,"height":1730,"sizeInBytes":1731},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/thumbnail_strapi_roadmap_from_scratch_c224fb6a01.png","thumbnail_strapi_roadmap_from_scratch_c224fb6a01","thumbnail_strapi-roadmap-from-scratch.png",80.46,234,156,80461,"strapi_roadmap_from_scratch_c224fb6a01",601.05,"https://awesome-friends-6b6e40fa18.media.strapiapp.com/strapi_roadmap_from_scratch_c224fb6a01.png","strapi-provider-upload-strapi-cloud","2026-03-14T03:21:35.663Z",{"id":1738,"documentId":1739,"name":1740,"slug":1741,"bio":1742,"createdAt":1743,"updatedAt":1743,"publishedAt":1744},1,"v47xc4w0scmvr4q884stes9o","Jose Henriquez","author","Desarrollador de software y estudiante de Ingeniería en Sistemas, apasionado por la tecnología, la creación de soluciones digitales y la construcción de proyectos con impacto real. Se caracteriza por ser una persona autodidacta, creativa y enfocada en convertir ideas en resultados concretos.","2026-03-08T18:07:58.711Z","2026-03-08T18:07:58.660Z",[1746,1793,1839,1884,1929],{"id":1747,"documentId":1748,"title":1749,"slug":1750,"excerpt":1751,"difficulty":1752,"estimatedCost":1753,"seoTitle":1754,"seoDescription":1755,"createdAt":1756,"updatedAt":1756,"publishedAt":1757,"maturity":1758,"coverImage":1759},4,"zu3qggap5kjtcwsfzkm1a1zf","Next.js + Sanity","nextjs-sanity","A flexible stack for content-rich websites that need strong editorial tooling, fast previews, and modern React-based frontend delivery.","intermediate","Medium depending on content volume, image delivery, preview usage, and hosting plan. seoTitle: Next.js + Sanity Stack Guide for Content Platforms and Modern Editorial Sites","Next.js + Sanity Stack Guide for Content Platforms and Modern Editorial Sites","Explore the Next.js + Sanity stack, including architecture, ideal use cases, benefits, trade-offs, and key documentation resources.","2026-03-08T18:51:03.536Z","2026-03-08T18:51:03.784Z","stable",{"id":1760,"documentId":1761,"name":1762,"alternativeText":1695,"caption":1695,"focalPoint":1695,"width":1696,"height":1697,"formats":1763,"hash":1788,"ext":1700,"mime":1703,"size":1789,"url":1790,"previewUrl":1695,"provider":1735,"provider_metadata":1695,"createdAt":1791,"updatedAt":1791,"publishedAt":1792},3,"ml2ee2zpq4kzbtab101u9ghd","sanitynextjs.png",{"large":1764,"small":1770,"medium":1776,"thumbnail":1782},{"ext":1700,"url":1765,"hash":1766,"mime":1703,"name":1767,"path":1695,"size":1768,"width":1706,"height":1707,"sizeInBytes":1769},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/large_sanitynextjs_18c9cce218.png","large_sanitynextjs_18c9cce218","large_sanitynextjs.png",915.04,915039,{"ext":1700,"url":1771,"hash":1772,"mime":1703,"name":1773,"path":1695,"size":1774,"width":1714,"height":1715,"sizeInBytes":1775},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/small_sanitynextjs_18c9cce218.png","small_sanitynextjs_18c9cce218","small_sanitynextjs.png",243.44,243439,{"ext":1700,"url":1777,"hash":1778,"mime":1703,"name":1779,"path":1695,"size":1780,"width":1722,"height":1714,"sizeInBytes":1781},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/medium_sanitynextjs_18c9cce218.png","medium_sanitynextjs_18c9cce218","medium_sanitynextjs.png",524.8,524801,{"ext":1700,"url":1783,"hash":1784,"mime":1703,"name":1785,"path":1695,"size":1786,"width":1729,"height":1730,"sizeInBytes":1787},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/thumbnail_sanitynextjs_18c9cce218.png","thumbnail_sanitynextjs_18c9cce218","thumbnail_sanitynextjs.png",62.39,62392,"sanitynextjs_18c9cce218",521.69,"https://awesome-friends-6b6e40fa18.media.strapiapp.com/sanitynextjs_18c9cce218.png","2026-03-08T18:46:03.464Z","2026-03-08T18:46:03.471Z",{"id":1794,"documentId":1795,"title":1796,"slug":1797,"excerpt":1798,"difficulty":11,"estimatedCost":1799,"seoTitle":1800,"seoDescription":1801,"createdAt":1802,"updatedAt":1803,"publishedAt":1804,"maturity":1758,"coverImage":1805},5,"ru06yk2a087zqapworwd6rsg","Nuxt 4 + Strapi 5","nuxt-4-strapi-5-primevue","A modern content-driven stack for SEO-friendly websites, blogs, documentation platforms, and scalable editorial projects.","Low to medium depending on hosting, media usage, and database provider.","Nuxt 4 + Strapi 5 + PrimeVueStack Guide for Modern Content-Driven Websites","Learn when to use Nuxt 4 with Strapi 5 and Prime Vue Components, its strengths, limitations, architecture patterns, and official resources for production-ready projects.","2026-03-08T18:43:39.573Z","2026-03-08T18:57:30.703Z","2026-03-08T18:57:30.958Z",{"id":1806,"documentId":1807,"name":1808,"alternativeText":1695,"caption":1695,"focalPoint":1695,"width":1696,"height":1697,"formats":1809,"hash":1834,"ext":1700,"mime":1703,"size":1835,"url":1836,"previewUrl":1695,"provider":1735,"provider_metadata":1695,"createdAt":1837,"updatedAt":1837,"publishedAt":1838},2,"b46gf1zi57op33uk2w07h9j6","modernwebdashboard.png",{"large":1810,"small":1816,"medium":1822,"thumbnail":1828},{"ext":1700,"url":1811,"hash":1812,"mime":1703,"name":1813,"path":1695,"size":1814,"width":1706,"height":1707,"sizeInBytes":1815},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/large_modernwebdashboard_b49d2560d2.png","large_modernwebdashboard_b49d2560d2","large_modernwebdashboard.png",990.81,990808,{"ext":1700,"url":1817,"hash":1818,"mime":1703,"name":1819,"path":1695,"size":1820,"width":1714,"height":1715,"sizeInBytes":1821},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/small_modernwebdashboard_b49d2560d2.png","small_modernwebdashboard_b49d2560d2","small_modernwebdashboard.png",268.68,268682,{"ext":1700,"url":1823,"hash":1824,"mime":1703,"name":1825,"path":1695,"size":1826,"width":1722,"height":1714,"sizeInBytes":1827},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/medium_modernwebdashboard_b49d2560d2.png","medium_modernwebdashboard_b49d2560d2","medium_modernwebdashboard.png",571.02,571018,{"ext":1700,"url":1829,"hash":1830,"mime":1703,"name":1831,"path":1695,"size":1832,"width":1729,"height":1730,"sizeInBytes":1833},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/thumbnail_modernwebdashboard_b49d2560d2.png","thumbnail_modernwebdashboard_b49d2560d2","thumbnail_modernwebdashboard.png",69.13,69125,"modernwebdashboard_b49d2560d2",574.58,"https://awesome-friends-6b6e40fa18.media.strapiapp.com/modernwebdashboard_b49d2560d2.png","2026-03-08T18:43:20.691Z","2026-03-08T18:43:20.698Z",{"id":1840,"documentId":1841,"title":1842,"slug":1843,"excerpt":1844,"difficulty":11,"estimatedCost":1845,"seoTitle":1846,"seoDescription":1847,"createdAt":1848,"updatedAt":1849,"publishedAt":1850,"maturity":1758,"coverImage":1851},14,"gkvptj1l6vok4xuii8vkj6qe","SvelteKit + Tailwind CSS for Modern Landing Pages","sveltekit-tailwind-css-for-modern-landing-pages","A flexible landing page stack for developers and startups who want modern design, strong performance, and room to grow into a more interactive web experience.","SvelteKit: Free, Tailwind CSS: Free, Hosting: Low or free to start, depending on provider, Optional extras: domain, analytics, forms, email services","SvelteKit + Tailwind CSS Stack Guide for Modern Landing Pages","Learn when to use SvelteKit with Tailwind CSS for landing pages, startup websites, marketing pages, and modern public-facing web experiences.","2026-03-10T03:32:55.146Z","2026-03-10T15:16:43.064Z","2026-03-10T15:16:43.505Z",{"id":1852,"documentId":1853,"name":1854,"alternativeText":1695,"caption":1695,"focalPoint":1695,"width":1696,"height":1697,"formats":1855,"hash":1880,"ext":1700,"mime":1703,"size":1881,"url":1882,"previewUrl":1695,"provider":1735,"provider_metadata":1695,"createdAt":1883,"updatedAt":1883,"publishedAt":1883},7,"dilgak8bwsjs0yty173tnbg9","svelkit-tailwindcss-landing-page.png",{"large":1856,"small":1862,"medium":1868,"thumbnail":1874},{"ext":1700,"url":1857,"hash":1858,"mime":1703,"name":1859,"path":1695,"size":1860,"width":1706,"height":1707,"sizeInBytes":1861},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/large_svelkit_tailwindcss_landing_page_232000d71f.png","large_svelkit_tailwindcss_landing_page_232000d71f","large_svelkit-tailwindcss-landing-page.png",932.81,932811,{"ext":1700,"url":1863,"hash":1864,"mime":1703,"name":1865,"path":1695,"size":1866,"width":1714,"height":1715,"sizeInBytes":1867},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/small_svelkit_tailwindcss_landing_page_232000d71f.png","small_svelkit_tailwindcss_landing_page_232000d71f","small_svelkit-tailwindcss-landing-page.png",262.08,262076,{"ext":1700,"url":1869,"hash":1870,"mime":1703,"name":1871,"path":1695,"size":1872,"width":1722,"height":1714,"sizeInBytes":1873},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/medium_svelkit_tailwindcss_landing_page_232000d71f.png","medium_svelkit_tailwindcss_landing_page_232000d71f","medium_svelkit-tailwindcss-landing-page.png",546.98,546980,{"ext":1700,"url":1875,"hash":1876,"mime":1703,"name":1877,"path":1695,"size":1878,"width":1729,"height":1730,"sizeInBytes":1879},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/thumbnail_svelkit_tailwindcss_landing_page_232000d71f.png","thumbnail_svelkit_tailwindcss_landing_page_232000d71f","thumbnail_svelkit-tailwindcss-landing-page.png",68.48,68477,"svelkit_tailwindcss_landing_page_232000d71f",540.74,"https://awesome-friends-6b6e40fa18.media.strapiapp.com/svelkit_tailwindcss_landing_page_232000d71f.png","2026-03-10T03:33:11.808Z",{"id":1885,"documentId":1886,"title":1887,"slug":1888,"excerpt":1889,"difficulty":11,"estimatedCost":1890,"seoTitle":1891,"seoDescription":1892,"createdAt":1893,"updatedAt":1894,"publishedAt":1895,"maturity":1758,"coverImage":1896},9,"yxti6jbq6ufd0biu3fx6ffpw","Astro with Content Collections  + Tailwind 4 + shadcn","astro-tailwind-css-v4-shadcn-ui-content-collections","A modern portfolio stack for developers, designers, and creators who want a fast personal website, polished project showcases, reusable UI components, and structured content without relying on a full CMS.","Astro free, Tailwind CSS free, shadcn/ui free, Content Collections built into Astro workflows, hosting low depending on provider.","Astro + Tailwind CSS v4 + shadcn/ui + Content Collections Stack Guide for Modern Portfolios","Learn when to use Astro with Tailwind CSS v4, shadcn/ui, and Content Collections for personal portfolios, developer websites, project showcases, and technical blogs.","2026-03-10T02:11:55.871Z","2026-03-10T02:31:48.345Z","2026-03-10T02:31:48.749Z",{"id":1794,"documentId":1897,"name":1898,"alternativeText":1695,"caption":1695,"focalPoint":1695,"width":1696,"height":1697,"formats":1899,"hash":1924,"ext":1700,"mime":1703,"size":1925,"url":1926,"previewUrl":1695,"provider":1735,"provider_metadata":1695,"createdAt":1927,"updatedAt":1927,"publishedAt":1928},"mekbtcfjrui3pj6ixju8k812","astro-content-collection-portfolio-development.png",{"large":1900,"small":1906,"medium":1912,"thumbnail":1918},{"ext":1700,"url":1901,"hash":1902,"mime":1703,"name":1903,"path":1695,"size":1904,"width":1706,"height":1707,"sizeInBytes":1905},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/large_astro_content_collection_portfolio_development_e57d75f3ad.png","large_astro_content_collection_portfolio_development_e57d75f3ad","large_astro-content-collection-portfolio-development.png",435.15,435147,{"ext":1700,"url":1907,"hash":1908,"mime":1703,"name":1909,"path":1695,"size":1910,"width":1714,"height":1715,"sizeInBytes":1911},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/small_astro_content_collection_portfolio_development_e57d75f3ad.png","small_astro_content_collection_portfolio_development_e57d75f3ad","small_astro-content-collection-portfolio-development.png",111.67,111674,{"ext":1700,"url":1913,"hash":1914,"mime":1703,"name":1915,"path":1695,"size":1916,"width":1722,"height":1714,"sizeInBytes":1917},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/medium_astro_content_collection_portfolio_development_e57d75f3ad.png","medium_astro_content_collection_portfolio_development_e57d75f3ad","medium_astro-content-collection-portfolio-development.png",241.38,241381,{"ext":1700,"url":1919,"hash":1920,"mime":1703,"name":1921,"path":1695,"size":1922,"width":1729,"height":1730,"sizeInBytes":1923},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/thumbnail_astro_content_collection_portfolio_development_e57d75f3ad.png","thumbnail_astro_content_collection_portfolio_development_e57d75f3ad","thumbnail_astro-content-collection-portfolio-development.png",30.25,30250,"astro_content_collection_portfolio_development_e57d75f3ad",239.93,"https://awesome-friends-6b6e40fa18.media.strapiapp.com/astro_content_collection_portfolio_development_e57d75f3ad.png","2026-03-10T02:29:59.242Z","2026-03-10T02:29:59.247Z",{"id":1930,"documentId":1931,"title":1932,"slug":1933,"excerpt":1934,"difficulty":11,"estimatedCost":1935,"seoTitle":1936,"seoDescription":1937,"createdAt":1938,"updatedAt":1938,"publishedAt":1939,"maturity":1758,"coverImage":1940},11,"mtna95wmkqzsahxvrwl7rc1r","Astro + Tailwind CSS for Modern Landing Pages","astro-tailwind-css-for-modern-landing-pages","A beginner-friendly stack for building fast, modern, and visually polished landing pages with strong performance and clean frontend architecture.","Astro: Free, Tailwind CSS: Free, Hosting: Low or free to start, depending on provider  Optional extras: domain, analytics, forms, email services","Astro + Tailwind CSS Stack Guide for Modern Landing Pages","Learn when to use Astro with Tailwind CSS for landing pages, product websites, startup pages, personal brands, and modern marketing sites.","2026-03-10T03:06:06.022Z","2026-03-10T03:06:06.300Z",{"id":1941,"documentId":1942,"name":1943,"alternativeText":1695,"caption":1695,"focalPoint":1695,"width":1944,"height":1945,"formats":1946,"hash":1976,"ext":1700,"mime":1703,"size":1977,"url":1978,"previewUrl":1695,"provider":1735,"provider_metadata":1695,"createdAt":1979,"updatedAt":1979,"publishedAt":1979},6,"ap2d2wcmasourkoh3f5l0wyi","cover-astro-tailwind-css-modern-landing-pages.png",1857,949,{"large":1947,"small":1954,"medium":1961,"thumbnail":1968},{"ext":1700,"url":1948,"hash":1949,"mime":1703,"name":1950,"path":1695,"size":1951,"width":1706,"height":1952,"sizeInBytes":1953},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/large_cover_astro_tailwind_css_modern_landing_pages_23162e0a23.png","large_cover_astro_tailwind_css_modern_landing_pages_23162e0a23","large_cover-astro-tailwind-css-modern-landing-pages.png",578.15,511,578145,{"ext":1700,"url":1955,"hash":1956,"mime":1703,"name":1957,"path":1695,"size":1958,"width":1714,"height":1959,"sizeInBytes":1960},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/small_cover_astro_tailwind_css_modern_landing_pages_23162e0a23.png","small_cover_astro_tailwind_css_modern_landing_pages_23162e0a23","small_cover-astro-tailwind-css-modern-landing-pages.png",134.93,256,134925,{"ext":1700,"url":1962,"hash":1963,"mime":1703,"name":1964,"path":1695,"size":1965,"width":1722,"height":1966,"sizeInBytes":1967},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/medium_cover_astro_tailwind_css_modern_landing_pages_23162e0a23.png","medium_cover_astro_tailwind_css_modern_landing_pages_23162e0a23","medium_cover-astro-tailwind-css-modern-landing-pages.png",304.81,383,304810,{"ext":1700,"url":1969,"hash":1970,"mime":1703,"name":1971,"path":1695,"size":1972,"width":1973,"height":1974,"sizeInBytes":1975},"https://awesome-friends-6b6e40fa18.media.strapiapp.com/thumbnail_cover_astro_tailwind_css_modern_landing_pages_23162e0a23.png","thumbnail_cover_astro_tailwind_css_modern_landing_pages_23162e0a23","thumbnail_cover-astro-tailwind-css-modern-landing-pages.png",43.63,245,125,43634,"cover_astro_tailwind_css_modern_landing_pages_23162e0a23",336.08,"https://awesome-friends-6b6e40fa18.media.strapiapp.com/cover_astro_tailwind_css_modern_landing_pages_23162e0a23.png","2026-03-10T03:05:54.962Z",{"pagination":1981},{"page":1738,"pageSize":1982,"pageCount":1738,"total":1738},25]