[{"data":1,"prerenderedAt":2846},["ShallowReactive",2],{"navigation_docs":3,"-tu-hoc-nuxt-4-cau-hoi-phong-van":420,"-tu-hoc-nuxt-4-cau-hoi-phong-van-surround":2841},[4,153],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":26},"Phỏng vấn .NET","i-lucide-briefcase","\u002Fphong-van","1.phong-van",[10,27,66,111,128],{"title":11,"icon":12,"path":13,"stem":14,"children":15,"page":26},"Tổng quan","i-lucide-compass","\u002Fphong-van\u002Ftong-quan","1.phong-van\u002F1.tong-quan",[16,21],{"title":17,"path":18,"stem":19,"icon":20},"Thị trường HCM","\u002Fphong-van\u002Ftong-quan\u002Fthi-truong","1.phong-van\u002F1.tong-quan\u002F1.thi-truong","i-lucide-trending-up",{"title":22,"path":23,"stem":24,"icon":25},"Lộ trình 7 ngày","\u002Fphong-van\u002Ftong-quan\u002Flo-trinh","1.phong-van\u002F1.tong-quan\u002F2.lo-trinh","i-lucide-calendar-days",false,{"title":22,"icon":25,"path":28,"stem":29,"children":30,"page":26},"\u002Fphong-van\u002Flo-trinh","1.phong-van\u002F2.lo-trinh",[31,36,41,46,51,56,61],{"title":32,"path":33,"stem":34,"icon":35},"Ngày 1 — C# cơ bản","\u002Fphong-van\u002Flo-trinh\u002Fngay-1-csharp-co-ban","1.phong-van\u002F2.lo-trinh\u002F1.ngay-1-csharp-co-ban","i-lucide-1",{"title":37,"path":38,"stem":39,"icon":40},"Ngày 2 — OOP và SOLID","\u002Fphong-van\u002Flo-trinh\u002Fngay-2-oop-solid","1.phong-van\u002F2.lo-trinh\u002F2.ngay-2-oop-solid","i-lucide-2",{"title":42,"path":43,"stem":44,"icon":45},"Ngày 3 — C# nâng cao","\u002Fphong-van\u002Flo-trinh\u002Fngay-3-csharp-nang-cao","1.phong-van\u002F2.lo-trinh\u002F3.ngay-3-csharp-nang-cao","i-lucide-3",{"title":47,"path":48,"stem":49,"icon":50},"Ngày 4 — Database và SQL","\u002Fphong-van\u002Flo-trinh\u002Fngay-4-database-sql","1.phong-van\u002F2.lo-trinh\u002F4.ngay-4-database-sql","i-lucide-4",{"title":52,"path":53,"stem":54,"icon":55},"Ngày 5 — ASP.NET Core và EF Core","\u002Fphong-van\u002Flo-trinh\u002Fngay-5-aspnet-efcore","1.phong-van\u002F2.lo-trinh\u002F5.ngay-5-aspnet-efcore","i-lucide-5",{"title":57,"path":58,"stem":59,"icon":60},"Ngày 6 — DSA coding","\u002Fphong-van\u002Flo-trinh\u002Fngay-6-dsa","1.phong-van\u002F2.lo-trinh\u002F6.ngay-6-dsa","i-lucide-6",{"title":62,"path":63,"stem":64,"icon":65},"Ngày 7 — Mock và HR","\u002Fphong-van\u002Flo-trinh\u002Fngay-7-mock-interview","1.phong-van\u002F2.lo-trinh\u002F7.ngay-7-mock-interview","i-lucide-7",{"title":67,"icon":68,"path":69,"stem":70,"children":71,"page":26},"Ngân hàng câu hỏi","i-lucide-database","\u002Fphong-van\u002Fngan-hang-cau-hoi","1.phong-van\u002F3.ngan-hang-cau-hoi",[72,77,82,87,92,97,102,107],{"title":73,"path":74,"stem":75,"icon":76},"C# (60+ câu)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fcsharp","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F1.csharp","i-lucide-hash",{"title":78,"path":79,"stem":80,"icon":81},"OOP và SOLID (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Foop","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F2.oop","i-lucide-shapes",{"title":83,"path":84,"stem":85,"icon":86},"SQL (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fsql","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F3.sql","i-lucide-database-zap",{"title":88,"path":89,"stem":90,"icon":91},"ASP.NET và EF (50+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-ef","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F4.aspnet-ef","i-lucide-server",{"title":93,"path":94,"stem":95,"icon":96},"DSA và Coding (30+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdsa-coding","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F5.dsa-coding","i-lucide-binary",{"title":98,"path":99,"stem":100,"icon":101},"HR và Soft skill (25+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fhr-behavior","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F6.hr-behavior","i-lucide-users",{"title":103,"path":104,"stem":105,"icon":106},"Design Pattern (55+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdesign-pattern","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F7.design-pattern","i-lucide-puzzle",{"title":108,"path":109,"stem":110,"icon":91},"ASP.NET MVC và Web API","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-mvc-webapi","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F8.aspnet-mvc-webapi",{"title":112,"itle":113,"icon":114,"path":115,"stem":116,"children":117,"page":26},"Tai Lieu","Tài liệu và Cheat sheet","i-lucide-book-marked","\u002Fphong-van\u002Ftai-lieu","1.phong-van\u002F4.tai-lieu",[118,123],{"title":119,"path":120,"stem":121,"icon":122},"Cheat Sheet","\u002Fphong-van\u002Ftai-lieu\u002Fcheatsheet","1.phong-van\u002F4.tai-lieu\u002F1.cheatsheet","i-lucide-clipboard-list",{"title":124,"path":125,"stem":126,"icon":127},"Nguồn tham khảo","\u002Fphong-van\u002Ftai-lieu\u002Fnguon","1.phong-van\u002F4.tai-lieu\u002F2.nguon","i-lucide-link",{"title":129,"icon":130,"path":131,"stem":132,"children":133,"page":26},"Phỏng vấn English","i-lucide-globe","\u002Fphong-van\u002Fenglish-interview","1.phong-van\u002F5.english-interview",[134,138,143,148],{"title":135,"path":136,"stem":137,"icon":130},"Tổng quan English","\u002Fphong-van\u002Fenglish-interview\u002Ftong-quan","1.phong-van\u002F5.english-interview\u002F1.tong-quan",{"title":139,"path":140,"stem":141,"icon":142},"Vocabulary","\u002Fphong-van\u002Fenglish-interview\u002Fvocabulary","1.phong-van\u002F5.english-interview\u002F2.vocabulary","i-lucide-book-a",{"title":144,"path":145,"stem":146,"icon":147},"Technical Q và A (EN)","\u002Fphong-van\u002Fenglish-interview\u002Ftechnical-en","1.phong-van\u002F5.english-interview\u002F3.technical-en","i-lucide-code",{"title":149,"path":150,"stem":151,"icon":152},"Behavioral (EN)","\u002Fphong-van\u002Fenglish-interview\u002Fbehavioral-en","1.phong-van\u002F5.english-interview\u002F4.behavioral-en","i-lucide-message-square-text",{"title":154,"icon":155,"path":156,"stem":157,"children":158},"Tự học","i-lucide-graduation-cap","\u002Ftu-hoc","2.tu-hoc",[159,161,287,310,333,357,384],{"title":154,"path":156,"stem":160,"icon":155},"2.tu-hoc\u002Findex",{"title":162,"icon":68,"path":163,"stem":164,"children":165},"Database","\u002Ftu-hoc\u002Fdatabase","2.tu-hoc\u002F1.database\u002Findex",[166,167,197,222,243,248],{"title":162,"path":163,"stem":164,"icon":68},{"title":168,"icon":91,"path":169,"stem":170,"children":171,"page":26},"SQL Server","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server","2.tu-hoc\u002F1.database\u002F2.sql-server",[172,177,182,187,192],{"title":173,"path":174,"stem":175,"icon":176},"1. Giới thiệu và Cài đặt","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F1.gioi-thieu-cai-dat","i-lucide-play-circle",{"title":178,"path":179,"stem":180,"icon":181},"2. Cú pháp cơ bản","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F2.cu-phap-co-ban","i-lucide-code-2",{"title":183,"path":184,"stem":185,"icon":186},"3. Truy vấn nâng cao","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F3.truy-van-nang-cao","i-lucide-git-merge",{"title":188,"path":189,"stem":190,"icon":191},"4. Đặc thù và Performance","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F4.dac-thu-performance","i-lucide-gauge",{"title":193,"path":194,"stem":195,"icon":196},"5. Q và A phỏng vấn","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F5.cau-hoi-phong-van","i-lucide-message-circle-question",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":26},"PostgreSQL","i-simple-icons-postgresql","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql","2.tu-hoc\u002F1.database\u002F3.postgresql",[203,206,209,212,215,218],{"title":173,"path":204,"stem":205,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":207,"stem":208,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F2.cu-phap-co-ban",{"title":183,"path":210,"stem":211,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F3.truy-van-nang-cao",{"title":188,"path":213,"stem":214,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F4.dac-thu-performance",{"title":193,"path":216,"stem":217,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F5.cau-hoi-phong-van",{"title":219,"path":220,"stem":221,"icon":96},"6. Tích hợp C# và Postgres","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftich-hop-csharp","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F6.tich-hop-csharp",{"title":223,"icon":224,"path":225,"stem":226,"children":227,"page":26},"MySQL","i-simple-icons-mysql","\u002Ftu-hoc\u002Fdatabase\u002Fmysql","2.tu-hoc\u002F1.database\u002F4.mysql",[228,231,234,237,240],{"title":173,"path":229,"stem":230,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F4.mysql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":232,"stem":233,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F4.mysql\u002F2.cu-phap-co-ban",{"title":183,"path":235,"stem":236,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F4.mysql\u002F3.truy-van-nang-cao",{"title":188,"path":238,"stem":239,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F4.mysql\u002F4.dac-thu-performance",{"title":193,"path":241,"stem":242,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F4.mysql\u002F5.cau-hoi-phong-van",{"title":244,"path":245,"stem":246,"icon":247},"So sánh 3 RDBMS","\u002Ftu-hoc\u002Fdatabase\u002Fso-sanh","2.tu-hoc\u002F1.database\u002F5.so-sanh","i-lucide-columns-3",{"title":249,"path":250,"stem":251,"children":252,"icon":254},"Supabase (BaaS)","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002Findex",[253,255,259,264,269,274,278,283],{"title":249,"path":250,"stem":251,"icon":254},"i-simple-icons-supabase",{"title":256,"path":257,"stem":258,"icon":68},"1. Database","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fdatabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002F1.database",{"title":260,"path":261,"stem":262,"icon":263},"2. Authentication","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fauthentication","2.tu-hoc\u002F1.database\u002F6.supabase\u002F2.authentication","i-lucide-key",{"title":265,"path":266,"stem":267,"icon":268},"3. Storage & Realtime","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fstorage-realtime","2.tu-hoc\u002F1.database\u002F6.supabase\u002F3.storage-realtime","i-lucide-zap",{"title":270,"path":271,"stem":272,"icon":273},"4. Edge Functions & AI","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Ffunctions-ai","2.tu-hoc\u002F1.database\u002F6.supabase\u002F4.functions-ai","i-lucide-brain",{"title":275,"path":276,"stem":277,"icon":181},"5. API & SDKs","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fapi-sdk","2.tu-hoc\u002F1.database\u002F6.supabase\u002F5.api-sdk",{"title":279,"path":280,"stem":281,"icon":282},"6. Platform & Deploy","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fplatform-deploy","2.tu-hoc\u002F1.database\u002F6.supabase\u002F6.platform-deploy","i-lucide-cloud",{"title":284,"path":285,"stem":286,"icon":196},"7. Interview & Q&A","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Finterview","2.tu-hoc\u002F1.database\u002F6.supabase\u002F7.interview",{"title":288,"icon":289,"path":290,"stem":291,"children":292},"TypeScript","i-simple-icons-typescript","\u002Ftu-hoc\u002Ftypescript","2.tu-hoc\u002F2.typescript\u002Findex",[293,294,297,301,306],{"title":288,"path":290,"stem":291,"icon":289},{"title":173,"path":295,"stem":296,"icon":176},"\u002Ftu-hoc\u002Ftypescript\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F2.typescript\u002F1.gioi-thieu-cai-dat",{"title":298,"path":299,"stem":300,"icon":81},"2. Type System","\u002Ftu-hoc\u002Ftypescript\u002Ftype-system","2.tu-hoc\u002F2.typescript\u002F2.type-system",{"title":302,"path":303,"stem":304,"icon":305},"3. Advanced types","\u002Ftu-hoc\u002Ftypescript\u002Fadvanced-types","2.tu-hoc\u002F2.typescript\u002F3.advanced-types","i-lucide-braces",{"title":307,"path":308,"stem":309,"icon":196},"4. Q và A phỏng vấn","\u002Ftu-hoc\u002Ftypescript\u002Fcau-hoi-phong-van","2.tu-hoc\u002F2.typescript\u002F4.cau-hoi-phong-van",{"title":311,"icon":81,"path":312,"stem":313,"children":314},"OOP","\u002Ftu-hoc\u002Foop","2.tu-hoc\u002F3.oop\u002Findex",[315,316,321,326,330],{"title":311,"path":312,"stem":313,"icon":81},{"title":317,"path":318,"stem":319,"icon":320},"1. Bốn tính chất","\u002Ftu-hoc\u002Foop\u002F4-tinh-chat","2.tu-hoc\u002F3.oop\u002F1.4-tinh-chat","i-lucide-circle-dot",{"title":322,"path":323,"stem":324,"icon":325},"2. SOLID","\u002Ftu-hoc\u002Foop\u002Fsolid","2.tu-hoc\u002F3.oop\u002F2.solid","i-lucide-shield",{"title":327,"path":328,"stem":329,"icon":106},"3. Design Pattern","\u002Ftu-hoc\u002Foop\u002Fdesign-pattern","2.tu-hoc\u002F3.oop\u002F3.design-pattern",{"title":307,"path":331,"stem":332,"icon":196},"\u002Ftu-hoc\u002Foop\u002Fcau-hoi-phong-van","2.tu-hoc\u002F3.oop\u002F4.cau-hoi-phong-van",{"title":334,"icon":305,"path":335,"stem":336,"children":337},"Generic","\u002Ftu-hoc\u002Fgeneric","2.tu-hoc\u002F4.generic\u002Findex",[338,339,344,349,354],{"title":334,"path":335,"stem":336,"icon":305},{"title":340,"path":341,"stem":342,"icon":343},"1. Khái niệm và cú pháp","\u002Ftu-hoc\u002Fgeneric\u002Fkhai-niem","2.tu-hoc\u002F4.generic\u002F1.khai-niem","i-lucide-book",{"title":345,"path":346,"stem":347,"icon":348},"2. Constraint và Variance","\u002Ftu-hoc\u002Fgeneric\u002Fconstraint-variance","2.tu-hoc\u002F4.generic\u002F2.constraint-variance","i-lucide-filter",{"title":350,"path":351,"stem":352,"icon":353},"3. C# vs TS","\u002Ftu-hoc\u002Fgeneric\u002Fso-sanh","2.tu-hoc\u002F4.generic\u002F3.so-sanh","i-lucide-git-compare",{"title":307,"path":355,"stem":356,"icon":196},"\u002Ftu-hoc\u002Fgeneric\u002Fcau-hoi-phong-van","2.tu-hoc\u002F4.generic\u002F4.cau-hoi-phong-van",{"title":358,"icon":359,"path":360,"stem":361,"children":362},"Nuxt 4","i-simple-icons-nuxt","\u002Ftu-hoc\u002Fnuxt-4","2.tu-hoc\u002F5.nuxt-4\u002Findex",[363,364,367,372,376,379],{"title":358,"path":360,"stem":361,"icon":359},{"title":173,"path":365,"stem":366,"icon":176},"\u002Ftu-hoc\u002Fnuxt-4\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F5.nuxt-4\u002F1.gioi-thieu-cai-dat",{"title":368,"path":369,"stem":370,"icon":371},"2. Routing và Rendering","\u002Ftu-hoc\u002Fnuxt-4\u002Frouting-rendering","2.tu-hoc\u002F5.nuxt-4\u002F2.routing-rendering","i-lucide-route",{"title":373,"path":374,"stem":375,"icon":91},"3. Data và Server","\u002Ftu-hoc\u002Fnuxt-4\u002Fdata-server","2.tu-hoc\u002F5.nuxt-4\u002F3.data-server",{"title":307,"path":377,"stem":378,"icon":196},"\u002Ftu-hoc\u002Fnuxt-4\u002Fcau-hoi-phong-van","2.tu-hoc\u002F5.nuxt-4\u002F4.cau-hoi-phong-van",{"title":380,"path":381,"stem":382,"icon":383},"5. Practical Todo App","\u002Ftu-hoc\u002Fnuxt-4\u002Fpractical-todo-app","2.tu-hoc\u002F5.nuxt-4\u002F5.practical-todo-app","i-lucide-check-square",{"title":385,"path":386,"stem":387,"children":388,"icon":390},"Tailwind CSS","\u002Ftu-hoc\u002Ftailwindcss","2.tu-hoc\u002F6.tailwindcss\u002Findex",[389,391,396,401,406,411,416],{"title":385,"path":386,"stem":387,"icon":390},"i-simple-icons-tailwindcss",{"title":392,"path":393,"stem":394,"icon":395},"1. Layout & Spacing","\u002Ftu-hoc\u002Ftailwindcss\u002Flayout-spacing","2.tu-hoc\u002F6.tailwindcss\u002F1.layout-spacing","i-lucide-layout",{"title":397,"path":398,"stem":399,"icon":400},"2. Typography & Colors","\u002Ftu-hoc\u002Ftailwindcss\u002Ftypography-colors","2.tu-hoc\u002F6.tailwindcss\u002F2.typography-colors","i-lucide-type",{"title":402,"path":403,"stem":404,"icon":405},"3. Interactive & Effects","\u002Ftu-hoc\u002Ftailwindcss\u002Finteractive-effects","2.tu-hoc\u002F6.tailwindcss\u002F3.interactive-effects","i-lucide-sparkles",{"title":407,"path":408,"stem":409,"icon":410},"4. Responsive & Dark Mode","\u002Ftu-hoc\u002Ftailwindcss\u002Fresponsive-darkmode","2.tu-hoc\u002F6.tailwindcss\u002F4.responsive-darkmode","i-lucide-monitor-smartphone",{"title":412,"path":413,"stem":414,"icon":415},"5. Customization & Theme","\u002Ftu-hoc\u002Ftailwindcss\u002Fcustomization","2.tu-hoc\u002F6.tailwindcss\u002F5.customization","i-lucide-settings-2",{"title":417,"path":418,"stem":419,"icon":181},"6. Practical Projects","\u002Ftu-hoc\u002Ftailwindcss\u002Fpractical-projects","2.tu-hoc\u002F6.tailwindcss\u002F6.practical-projects",{"id":421,"title":422,"body":423,"description":2834,"extension":2835,"links":2836,"meta":2837,"navigation":2838,"path":377,"seo":2839,"stem":378,"__hash__":2840},"docs\u002F2.tu-hoc\u002F5.nuxt-4\u002F4.cau-hoi-phong-van.md","Câu hỏi phỏng vấn Nuxt 4",{"type":424,"value":425,"toc":2723},"minimark",[426,431,436,440,444,476,480,491,495,509,513,523,527,533,537,541,565,569,582,594,606,618,632,642,656,660,673,681,684,698,709,713,717,743,747,754,863,867,880,884,892,899,905,915,927,931,942,954,963,975,982,989,996,1013,1024,1031,1042,1054,1062,1124,1127,1131,1136,1212,1218,1222,1230,1237,1300,1307,1317,1321,1348,1354,1364,1368,1372,1375,1379,1391,1395,1420,1424,1469,1473,1544,1548,1554,1558,1565,1569,1579,1595,1599,1659,1663,1676,1680,1684,1687,1691,1731,1735,1786,1790,1794,1806,1817,1834,1838,1861,1865,1869,1887,1890,1894,1900,1930,1933,1937,1946,1996,2000,2039,2047,2061,2065,2076,2080,2084,2091,2095,2101,2155,2159,2182,2189,2195,2201,2210,2214,2340,2343,2347,2361,2365,2386,2392,2396,2412,2498,2506,2510,2516,2674,2678,2698,2719],[427,428,430],"h2",{"id":429},"a-tổng-quan-nuxt-4","A. Tổng quan & Nuxt 4",[432,433,435],"h3",{"id":434},"_1-nuxt-là-gì","1. Nuxt là gì?",[437,438,439],"p",{},"Meta-framework xây trên Vue 3, kèm sẵn file-based routing, SSR\u002FSSG\u002FHybrid rendering, auto-import, server engine Nitro, module ecosystem. Tương đương Next.js cho React.",[432,441,443],{"id":442},"_2-nuxt-4-có-gì-khác-nuxt-3","2. Nuxt 4 có gì khác Nuxt 3?",[445,446,447,459,464,470,473],"ul",{},[448,449,450,458],"li",{},[451,452,453,454],"strong",{},"Cấu trúc ",[455,456,457],"code",{},"app\u002F"," mới — code app tách khỏi config.",[448,460,461,463],{},[451,462,288],{}," chia 3 project (app\u002Fserver\u002Fshared).",[448,465,466,469],{},[451,467,468],{},"Data fetching"," auto share theo key, auto cleanup, clear-on-refetch.",[448,471,472],{},"Drop Nuxt 2 compat.",[448,474,475],{},"Migration codemod tự động.",[432,477,479],{"id":478},"_3-nuxt-4-release-khi-nào-nuxt-3-còn-support","3. Nuxt 4 release khi nào? Nuxt 3 còn support?",[437,481,482,483,486,487,490],{},"Nuxt 4.0 release ",[451,484,485],{},"07\u002F2025",". Nuxt 3 support đến ",[451,488,489],{},"01\u002F2026",", kèm backport feature.",[432,492,494],{"id":493},"_4-vì-sao-chia-3-ts-project","4. Vì sao chia 3 TS project?",[437,496,497,500,501,504,505,508],{},[455,498,499],{},"tsconfig.app.json"," (client + universal), ",[455,502,503],{},"tsconfig.server.json"," (Node + Nitro), ",[455,506,507],{},"tsconfig.shared.json"," (strict both). → Type chính xác hơn, server-only util không leak sang client lúc compile.",[432,510,512],{"id":511},"_5-có-nên-migrate-từ-nuxt-3","5. Có nên migrate từ Nuxt 3?",[437,514,515,518,519,522],{},[455,516,517],{},"npx nuxt upgrade --dedupe"," + ",[455,520,521],{},"npx codemod@latest nuxt\u002F4\u002Fmigration-recipe"," thường xong vài phút. Migrate khi có thời gian — không gấp vì Nuxt 3 còn support.",[432,524,526],{"id":525},"_6-compatibility-date-là-gì","6. Compatibility date là gì?",[437,528,529,532],{},[455,530,531],{},"compatibilityDate: '2025-07-01'"," trong nuxt.config — pin behavior tại 1 thời điểm để upgrade Nuxt không bất ngờ vỡ.",[427,534,536],{"id":535},"b-routing","B. Routing",[432,538,540],{"id":539},"_7-file-based-routing-trong-nuxt-quy-ước","7. File-based routing trong Nuxt — quy ước?",[437,542,543,546,547,550,551,546,554,550,557,560,561,564],{},[455,544,545],{},"app\u002Fpages\u002Findex.vue"," → ",[455,548,549],{},"\u002F",". ",[455,552,553],{},"app\u002Fpages\u002Fusers\u002F[id].vue",[455,555,556],{},"\u002Fusers\u002F:id",[455,558,559],{},"[...slug].vue"," catch-all. ",[455,562,563],{},"[[tab]].vue"," optional param.",[432,566,568],{"id":567},"_8-nested-route","8. Nested route?",[437,570,571,518,574,577,578,581],{},[455,572,573],{},"app\u002Fpages\u002Fparent.vue",[455,575,576],{},"app\u002Fpages\u002Fparent\u002Fchild.vue",". Parent có ",[455,579,580],{},"\u003CNuxtPage \u002F>"," để render child.",[432,583,585,586,589,590,593],{"id":584},"_9-nuxtlink-khác-a-ra-sao","9. ",[455,587,588],{},"\u003CNuxtLink>"," khác ",[455,591,592],{},"\u003Ca>"," ra sao?",[437,595,596,598,599,601,602,605],{},[455,597,588],{}," client-side navigation, auto prefetch khi visible viewport. ",[455,600,592],{}," full reload page. External link dùng ",[455,603,604],{},"\u003CNuxtLink external>",".",[432,607,609,610,613,614,617],{"id":608},"_10-useroute-vs-userouter","10. ",[455,611,612],{},"useRoute"," vs ",[455,615,616],{},"useRouter","?",[445,619,620,626],{},[448,621,622,625],{},[455,623,624],{},"useRoute()",": route hiện tại (path, params, query) — reactive.",[448,627,628,631],{},[455,629,630],{},"useRouter()",": programmatic navigation (push, replace, back).",[432,633,635,636,613,639,617],{"id":634},"_11-navigateto-vs-routerpush","11. ",[455,637,638],{},"navigateTo",[455,640,641],{},"router.push",[445,643,644,650],{},[448,645,646,649],{},[455,647,648],{},"navigateTo(\"\u002Fx\")",": cả server (SSR redirect) và client. Khuyến nghị dùng cái này.",[448,651,652,655],{},[455,653,654],{},"router.push(\"\u002Fx\")",": chỉ client.",[432,657,659],{"id":658},"_12-middleware-nuxt-khác-vue-router-beforeeach","12. Middleware Nuxt khác Vue Router beforeEach?",[437,661,662,663,550,666,669,670,605],{},"Middleware Nuxt chạy ",[451,664,665],{},"cả server SSR lẫn client",[455,667,668],{},"*.global.ts"," → mọi route. Còn lại register qua ",[455,671,672],{},"definePageMeta({ middleware: \"...\" })",[432,674,676,677,680],{"id":675},"_13-definepagemeta-dùng-làm-gì","13. ",[455,678,679],{},"definePageMeta"," dùng làm gì?",[437,682,683],{},"Config per-page: layout, middleware, validate, transition, scroll behavior.",[432,685,687,688,691,692,589,695,617],{"id":686},"_14-nuxtpage-và-nuxtlayout-khác-routerview","14. ",[455,689,690],{},"\u003CNuxtPage>"," và ",[455,693,694],{},"\u003CNuxtLayout>",[455,696,697],{},"\u003CRouterView>",[437,699,700,702,703,705,706,708],{},[455,701,690],{}," = ",[455,704,697],{}," + thêm transition + keep-alive. ",[455,707,694],{}," wrap chọn layout.",[427,710,712],{"id":711},"c-rendering-modes","C. Rendering modes",[432,714,716],{"id":715},"_15-ssr-vs-ssg-vs-spa-vs-isr","15. SSR vs SSG vs SPA vs ISR?",[445,718,719,725,731,737],{},[448,720,721,724],{},[451,722,723],{},"SSR",": server render mỗi request.",[448,726,727,730],{},[451,728,729],{},"SSG",": build time → static HTML.",[448,732,733,736],{},[451,734,735],{},"SPA",": client only, không server render.",[448,738,739,742],{},[451,740,741],{},"ISR",": SSG + revalidate sau N giây.",[432,744,746],{"id":745},"_16-hybrid-rendering-trong-nuxt-4","16. Hybrid rendering trong Nuxt 4?",[437,748,749,750,753],{},"Mỗi route 1 mode khác nhau qua ",[455,751,752],{},"routeRules",":",[755,756,761],"pre",{"className":757,"code":758,"language":759,"meta":760,"style":760},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","routeRules: {\n  \"\u002F\": { prerender: true },\n  \"\u002Fblog\u002F**\": { isr: 600 },\n  \"\u002Fadmin\u002F**\": { ssr: false },\n}\n","ts","",[455,762,763,777,808,833,857],{"__ignoreMap":760},[764,765,768,771,774],"span",{"class":766,"line":767},"line",1,[764,769,752],{"class":770},"sBMFI",[764,772,753],{"class":773},"sMK4o",[764,775,776],{"class":773}," {\n",[764,778,780,783,786,789,793,796,799,801,805],{"class":766,"line":779},2,[764,781,782],{"class":773},"  \"",[764,784,549],{"class":785},"sfazB",[764,787,788],{"class":773},"\"",[764,790,792],{"class":791},"swJcz",": ",[764,794,795],{"class":773},"{",[764,797,798],{"class":791}," prerender",[764,800,753],{"class":773},[764,802,804],{"class":803},"sfNiH"," true",[764,806,807],{"class":773}," },\n",[764,809,811,813,816,818,820,822,825,827,831],{"class":766,"line":810},3,[764,812,782],{"class":773},[764,814,815],{"class":785},"\u002Fblog\u002F**",[764,817,788],{"class":773},[764,819,792],{"class":791},[764,821,795],{"class":773},[764,823,824],{"class":791}," isr",[764,826,753],{"class":773},[764,828,830],{"class":829},"sbssI"," 600",[764,832,807],{"class":773},[764,834,836,838,841,843,845,847,850,852,855],{"class":766,"line":835},4,[764,837,782],{"class":773},[764,839,840],{"class":785},"\u002Fadmin\u002F**",[764,842,788],{"class":773},[764,844,792],{"class":791},[764,846,795],{"class":773},[764,848,849],{"class":791}," ssr",[764,851,753],{"class":773},[764,853,854],{"class":803}," false",[764,856,807],{"class":773},[764,858,860],{"class":766,"line":859},5,[764,861,862],{"class":773},"}\n",[432,864,866],{"id":865},"_17-isr-vs-swr","17. ISR vs SWR?",[445,868,869,874],{},[448,870,871,873],{},[451,872,741],{},": cache cho đến hết TTL, request đầu sau TTL block để regenerate.",[448,875,876,879],{},[451,877,878],{},"SWR",": trả ngay cached (stale), regenerate background.",[432,881,883],{"id":882},"_18-khi-nào-dùng-ssr-khi-nào-spa","18. Khi nào dùng SSR, khi nào SPA?",[445,885,886,889],{},[448,887,888],{},"SSR: SEO quan trọng (marketing, blog, product page), first paint nhanh.",[448,890,891],{},"SPA: dashboard auth-gated, không cần SEO, UX kiểu app.",[432,893,895,896,898],{"id":894},"_19-routerules-đặt-ở-đâu","19. ",[455,897,752],{}," đặt ở đâu?",[437,900,901,904],{},[455,902,903],{},"nuxt.config.ts",". Apply lúc build + runtime — không cần redeploy mọi route.",[432,906,908,909,589,912,617],{"id":907},"_20-prerender-true-khác-ssr-false","20. ",[455,910,911],{},"prerender: true",[455,913,914],{},"ssr: false",[445,916,917,922],{},[448,918,919,921],{},[455,920,911],{}," (SSG): build time → HTML. Không cần Node server.",[448,923,924,926],{},[455,925,914],{}," (SPA): client render, vẫn cần server serve index.html.",[427,928,930],{"id":929},"d-data-fetching","D. Data fetching",[432,932,934,935,613,938,941],{"id":933},"_21-usefetch-vs-fetch-khác-gì","21. ",[455,936,937],{},"useFetch",[455,939,940],{},"$fetch"," khác gì?",[445,943,944,949],{},[448,945,946,948],{},[455,947,937],{},": SSR-aware, reactive (data, pending, error), cache key, chỉ chạy 1 lần SSR rồi hydrate.",[448,950,951,953],{},[455,952,940],{},": Promise raw, không reactive, không SSR-aware. Dùng cho event handler \u002F form submit.",[432,955,957,958,613,960,617],{"id":956},"_22-usefetch-vs-useasyncdata","22. ",[455,959,937],{},[455,961,962],{},"useAsyncData",[437,964,965,967,968,518,970,550,972,974],{},[455,966,937],{}," là wrapper cao cấp của ",[455,969,962],{},[455,971,940],{},[455,973,962],{}," linh hoạt hơn — function bất kỳ trả Promise, combine nhiều API call.",[432,976,978,979,981],{"id":977},"_23-vì-sao-usefetch-ssr-aware","23. Vì sao ",[455,980,937],{}," SSR-aware?",[437,983,984,985,988],{},"Chạy 1 lần ở server → kết quả serialize vào HTML payload → client hydrate ",[451,986,987],{},"không gọi lại"," API. Vừa SEO vừa nhanh first paint.",[432,990,992,993,995],{"id":991},"_24-usefetch-nuxt-4-khác-nuxt-3","24. ",[455,994,937],{}," Nuxt 4 khác Nuxt 3?",[445,997,998,1001,1004,1007,1010],{},[448,999,1000],{},"Auto share data cùng key.",[448,1002,1003],{},"Auto cleanup khi unmount.",[448,1005,1006],{},"Refetch → clear data về null (Nuxt 3 giữ stale data).",[448,1008,1009],{},"Reactive key tự refetch.",[448,1011,1012],{},"Abort control (4.2+).",[432,1014,1016,1017,1020,1021,1023],{"id":1015},"_25-lazy-true-trong-usefetch-để-làm-gì","25. ",[455,1018,1019],{},"lazy: true"," trong ",[455,1022,937],{}," để làm gì?",[437,1025,1026,1027,1030],{},"Không block navigation tới khi fetch xong — page render ngay, ",[455,1028,1029],{},"pending = true",", data tới sau.",[432,1032,1034,1035,691,1038,1041],{"id":1033},"_26-pick-và-transform-trong-usefetch","26. ",[455,1036,1037],{},"pick",[455,1039,1040],{},"transform"," trong useFetch?",[445,1043,1044,1049],{},[448,1045,1046,1048],{},[455,1047,1037],{},": chỉ giữ fields trong response → giảm payload.",[448,1050,1051,1053],{},[455,1052,1040],{},": biến đổi response trước khi cache.",[432,1055,1057,1058,1061],{"id":1056},"_27-watch-option-để-làm-gì","27. ",[455,1059,1060],{},"watch"," option để làm gì?",[755,1063,1065],{"className":757,"code":1064,"language":759,"meta":760,"style":760},"useFetch(\"\u002Fapi\u002Fusers\", { query: { city: filter }, watch: [filter] });\n",[455,1066,1067],{"__ignoreMap":760},[764,1068,1069,1072,1076,1078,1081,1083,1086,1089,1092,1094,1096,1099,1101,1104,1107,1110,1112,1115,1118,1121],{"class":766,"line":767},[764,1070,937],{"class":1071},"s2Zo4",[764,1073,1075],{"class":1074},"sTEyZ","(",[764,1077,788],{"class":773},[764,1079,1080],{"class":785},"\u002Fapi\u002Fusers",[764,1082,788],{"class":773},[764,1084,1085],{"class":773},",",[764,1087,1088],{"class":773}," {",[764,1090,1091],{"class":791}," query",[764,1093,753],{"class":773},[764,1095,1088],{"class":773},[764,1097,1098],{"class":791}," city",[764,1100,753],{"class":773},[764,1102,1103],{"class":1074}," filter ",[764,1105,1106],{"class":773},"},",[764,1108,1109],{"class":791}," watch",[764,1111,753],{"class":773},[764,1113,1114],{"class":1074}," [filter] ",[764,1116,1117],{"class":773},"}",[764,1119,1120],{"class":1074},")",[764,1122,1123],{"class":773},";\n",[437,1125,1126],{},"Auto refetch khi reactive value đổi.",[432,1128,1130],{"id":1129},"_28-làm-sao-gọi-api-trên-button-click","28. Làm sao gọi API trên button click?",[437,1132,1133,1134,753],{},"Dùng ",[455,1135,940],{},[755,1137,1139],{"className":757,"code":1138,"language":759,"meta":760,"style":760},"async function save() { await $fetch(\"\u002Fapi\u002Fsave\", { method: \"POST\", body: data }); }\n",[455,1140,1141],{"__ignoreMap":760},[764,1142,1143,1147,1150,1153,1156,1158,1162,1165,1167,1169,1172,1174,1176,1178,1181,1183,1186,1189,1191,1193,1196,1198,1201,1204,1206,1209],{"class":766,"line":767},[764,1144,1146],{"class":1145},"spNyl","async",[764,1148,1149],{"class":1145}," function",[764,1151,1152],{"class":1071}," save",[764,1154,1155],{"class":773},"()",[764,1157,1088],{"class":773},[764,1159,1161],{"class":1160},"s7zQu"," await",[764,1163,1164],{"class":1071}," $fetch",[764,1166,1075],{"class":791},[764,1168,788],{"class":773},[764,1170,1171],{"class":785},"\u002Fapi\u002Fsave",[764,1173,788],{"class":773},[764,1175,1085],{"class":773},[764,1177,1088],{"class":773},[764,1179,1180],{"class":791}," method",[764,1182,753],{"class":773},[764,1184,1185],{"class":773}," \"",[764,1187,1188],{"class":785},"POST",[764,1190,788],{"class":773},[764,1192,1085],{"class":773},[764,1194,1195],{"class":791}," body",[764,1197,753],{"class":773},[764,1199,1200],{"class":1074}," data",[764,1202,1203],{"class":773}," }",[764,1205,1120],{"class":791},[764,1207,1208],{"class":773},";",[764,1210,1211],{"class":773}," }\n",[437,1213,1214,1215,1217],{},"Không dùng ",[455,1216,937],{}," trong handler — nó cho data declarative khi load page.",[427,1219,1221],{"id":1220},"e-state-management","E. State management",[432,1223,1225,1226,1229],{"id":1224},"_29-usestate-là-gì","29. ",[455,1227,1228],{},"useState"," là gì?",[437,1231,1232,1233,1236],{},"Cross-component state SSR-safe. Khác ",[455,1234,1235],{},"ref"," module-level: scope theo request ở SSR.",[755,1238,1240],{"className":757,"code":1239,"language":759,"meta":760,"style":760},"export const useAuth = () => useState(\"auth\", () => ({ user: null }));\n",[455,1241,1242],{"__ignoreMap":760},[764,1243,1244,1247,1250,1253,1256,1259,1262,1265,1267,1269,1272,1274,1276,1278,1280,1283,1285,1288,1290,1293,1295,1298],{"class":766,"line":767},[764,1245,1246],{"class":1160},"export",[764,1248,1249],{"class":1145}," const",[764,1251,1252],{"class":1074}," useAuth ",[764,1254,1255],{"class":773},"=",[764,1257,1258],{"class":773}," ()",[764,1260,1261],{"class":1145}," =>",[764,1263,1264],{"class":1071}," useState",[764,1266,1075],{"class":1074},[764,1268,788],{"class":773},[764,1270,1271],{"class":785},"auth",[764,1273,788],{"class":773},[764,1275,1085],{"class":773},[764,1277,1258],{"class":773},[764,1279,1261],{"class":1145},[764,1281,1282],{"class":1074}," (",[764,1284,795],{"class":773},[764,1286,1287],{"class":791}," user",[764,1289,753],{"class":773},[764,1291,1292],{"class":773}," null",[764,1294,1203],{"class":773},[764,1296,1297],{"class":1074},"))",[764,1299,1123],{"class":773},[432,1301,1303,1304,1306],{"id":1302},"_30-khi-nào-dùng-usestate-vs-pinia","30. Khi nào dùng ",[455,1305,1228],{}," vs Pinia?",[445,1308,1309,1314],{},[448,1310,1311,1313],{},[455,1312,1228],{},": state đơn giản, scope nhỏ.",[448,1315,1316],{},"Pinia: store phức tạp, có action async, devtools, modular.",[432,1318,1320],{"id":1319},"_31-ssr-hydration-mismatch-tránh-ra-sao","31. SSR hydration mismatch — tránh ra sao?",[445,1322,1323,1331,1342],{},[448,1324,1133,1325,1327,1328,1330],{},[455,1326,1228],{}," thay ",[455,1329,1235],{}," module-level cho shared state.",[448,1332,1333,1334,1337,1338,1341],{},"Tránh ",[455,1335,1336],{},"Math.random()",", ",[455,1339,1340],{},"Date.now()"," ở component gây khác giữa server và client.",[448,1343,1344,1345,605],{},"Wrap client-only bằng ",[455,1346,1347],{},"\u003CClientOnly>",[432,1349,1351,1352,1023],{"id":1350},"_32-clientonly-để-làm-gì","32. ",[455,1353,1347],{},[437,1355,1356,1357,1337,1360,1363],{},"Skip render component ở SSR — chỉ hydrate ở client. Dùng cho component dùng ",[455,1358,1359],{},"window",[455,1361,1362],{},"localStorage",", lib client-only.",[427,1365,1367],{"id":1366},"f-server-nitro","F. Server \u002F Nitro",[432,1369,1371],{"id":1370},"_33-nitro-là-gì","33. Nitro là gì?",[437,1373,1374],{},"Server engine của Nuxt — đảm nhiệm SSR + API route + middleware. Deploy đa nền tảng (Node, Vercel, Cloudflare, Deno, Bun, Lambda).",[432,1376,1378],{"id":1377},"_34-server-route-convention","34. Server route convention?",[437,1380,1381,1384,1385,546,1388,605],{},[455,1382,1383],{},"server\u002Fapi\u002F\u003Cpath>.\u003Cmethod>.ts"," → endpoint. Ví dụ ",[455,1386,1387],{},"server\u002Fapi\u002Fusers\u002F[id].get.ts",[455,1389,1390],{},"GET \u002Fapi\u002Fusers\u002F:id",[432,1392,1394],{"id":1393},"_35-đọc-body-request","35. Đọc body request?",[755,1396,1398],{"className":757,"code":1397,"language":759,"meta":760,"style":760},"const body = await readBody(event);\n",[455,1399,1400],{"__ignoreMap":760},[764,1401,1402,1405,1408,1410,1412,1415,1418],{"class":766,"line":767},[764,1403,1404],{"class":1145},"const",[764,1406,1407],{"class":1074}," body ",[764,1409,1255],{"class":773},[764,1411,1161],{"class":1160},[764,1413,1414],{"class":1071}," readBody",[764,1416,1417],{"class":1074},"(event)",[764,1419,1123],{"class":773},[432,1421,1423],{"id":1422},"_36-throw-error-404","36. Throw error 404?",[755,1425,1427],{"className":757,"code":1426,"language":759,"meta":760,"style":760},"throw createError({ statusCode: 404, statusMessage: \"Not Found\" });\n",[455,1428,1429],{"__ignoreMap":760},[764,1430,1431,1434,1437,1439,1441,1444,1446,1449,1451,1454,1456,1458,1461,1463,1465,1467],{"class":766,"line":767},[764,1432,1433],{"class":1160},"throw",[764,1435,1436],{"class":1071}," createError",[764,1438,1075],{"class":1074},[764,1440,795],{"class":773},[764,1442,1443],{"class":791}," statusCode",[764,1445,753],{"class":773},[764,1447,1448],{"class":829}," 404",[764,1450,1085],{"class":773},[764,1452,1453],{"class":791}," statusMessage",[764,1455,753],{"class":773},[764,1457,1185],{"class":773},[764,1459,1460],{"class":785},"Not Found",[764,1462,788],{"class":773},[764,1464,1203],{"class":773},[764,1466,1120],{"class":1074},[764,1468,1123],{"class":773},[432,1470,1472],{"id":1471},"_37-set-cookie","37. Set cookie?",[755,1474,1476],{"className":757,"code":1475,"language":759,"meta":760,"style":760},"setCookie(event, \"session\", \"abc\", { httpOnly: true, secure: true, sameSite: \"lax\" });\n",[455,1477,1478],{"__ignoreMap":760},[764,1479,1480,1483,1486,1488,1490,1493,1495,1497,1499,1502,1504,1506,1508,1511,1513,1515,1517,1520,1522,1524,1526,1529,1531,1533,1536,1538,1540,1542],{"class":766,"line":767},[764,1481,1482],{"class":1071},"setCookie",[764,1484,1485],{"class":1074},"(event",[764,1487,1085],{"class":773},[764,1489,1185],{"class":773},[764,1491,1492],{"class":785},"session",[764,1494,788],{"class":773},[764,1496,1085],{"class":773},[764,1498,1185],{"class":773},[764,1500,1501],{"class":785},"abc",[764,1503,788],{"class":773},[764,1505,1085],{"class":773},[764,1507,1088],{"class":773},[764,1509,1510],{"class":791}," httpOnly",[764,1512,753],{"class":773},[764,1514,804],{"class":803},[764,1516,1085],{"class":773},[764,1518,1519],{"class":791}," secure",[764,1521,753],{"class":773},[764,1523,804],{"class":803},[764,1525,1085],{"class":773},[764,1527,1528],{"class":791}," sameSite",[764,1530,753],{"class":773},[764,1532,1185],{"class":773},[764,1534,1535],{"class":785},"lax",[764,1537,788],{"class":773},[764,1539,1203],{"class":773},[764,1541,1120],{"class":1074},[764,1543,1123],{"class":773},[432,1545,1547],{"id":1546},"_38-server-middleware-chạy-khi-nào","38. Server middleware chạy khi nào?",[437,1549,1550,1553],{},[455,1551,1552],{},"server\u002Fmiddleware\u002F*.ts"," → mọi request. Dùng cho auth, logging.",[432,1555,1557],{"id":1556},"_39-nitro-storage-layer-là-gì","39. Nitro storage layer là gì?",[437,1559,1560,1561,1564],{},"Abstract KV store qua nhiều backend (memory, filesystem, Redis, Cloudflare KV). ",[455,1562,1563],{},"useStorage(\"cache\")",". Tiện cho cache.",[427,1566,1568],{"id":1567},"g-runtime-config","G. Runtime config",[432,1570,1572,1573,613,1576,617],{"id":1571},"_40-runtimeconfig-vs-appconfig","40. ",[455,1574,1575],{},"runtimeConfig",[455,1577,1578],{},"appConfig",[445,1580,1581,1590],{},[448,1582,1583,1585,1586,1589],{},[455,1584,1575],{},": env-var, server secret, có thể override runtime. Key trong ",[455,1587,1588],{},"public"," mới expose client.",[448,1591,1592,1594],{},[455,1593,1578],{},": reactive, exposed client, KHÔNG cho secret.",[432,1596,1598],{"id":1597},"_41-đọc-env-var","41. Đọc env var?",[755,1600,1602],{"className":757,"code":1601,"language":759,"meta":760,"style":760},"\u002F\u002F .env: NUXT_API_SECRET=xxx, NUXT_PUBLIC_API_BASE=https:\u002F\u002Fapi...\nconst config = useRuntimeConfig();\nconfig.apiSecret;            \u002F\u002F server only\nconfig.public.apiBase;       \u002F\u002F both\n",[455,1603,1604,1610,1626,1641],{"__ignoreMap":760},[764,1605,1606],{"class":766,"line":767},[764,1607,1609],{"class":1608},"sHwdD","\u002F\u002F .env: NUXT_API_SECRET=xxx, NUXT_PUBLIC_API_BASE=https:\u002F\u002Fapi...\n",[764,1611,1612,1614,1617,1619,1622,1624],{"class":766,"line":779},[764,1613,1404],{"class":1145},[764,1615,1616],{"class":1074}," config ",[764,1618,1255],{"class":773},[764,1620,1621],{"class":1071}," useRuntimeConfig",[764,1623,1155],{"class":1074},[764,1625,1123],{"class":773},[764,1627,1628,1631,1633,1636,1638],{"class":766,"line":810},[764,1629,1630],{"class":1074},"config",[764,1632,605],{"class":773},[764,1634,1635],{"class":1074},"apiSecret",[764,1637,1208],{"class":773},[764,1639,1640],{"class":1608},"            \u002F\u002F server only\n",[764,1642,1643,1645,1647,1649,1651,1654,1656],{"class":766,"line":835},[764,1644,1630],{"class":1074},[764,1646,605],{"class":773},[764,1648,1588],{"class":1074},[764,1650,605],{"class":773},[764,1652,1653],{"class":1074},"apiBase",[764,1655,1208],{"class":773},[764,1657,1658],{"class":1608},"       \u002F\u002F both\n",[432,1660,1662],{"id":1661},"_42-bí-mật-env-có-thể-leak-client","42. Bí mật env có thể leak client?",[437,1664,1665,1666,1669,1670,1672,1673,1675],{},"Có nếu để trong ",[455,1667,1668],{},"runtimeConfig.public"," hoặc ",[455,1671,1578],{},". Chỉ field ngoài ",[455,1674,1588],{}," mới server-only.",[427,1677,1679],{"id":1678},"h-auto-import","H. Auto-import",[432,1681,1683],{"id":1682},"_43-auto-import-có-overhead-bundle-không","43. Auto-import có overhead bundle không?",[437,1685,1686],{},"Không. Nuxt scan + add import statement lúc build. Output có import explicit, tree-shake bình thường.",[432,1688,1690],{"id":1689},"_44-cái-gì-được-auto-import","44. Cái gì được auto-import?",[445,1692,1693,1698,1706,1720],{},[448,1694,1695],{},[455,1696,1697],{},"app\u002Fcomponents\u002F**",[448,1699,1700,1337,1703],{},[455,1701,1702],{},"app\u002Fcomposables\u002F**",[455,1704,1705],{},"shared\u002Futils\u002F**",[448,1707,1708,1709,1337,1711,1337,1714,1337,1716,1719],{},"Vue API (",[455,1710,1235],{},[455,1712,1713],{},"computed",[455,1715,1060],{},[455,1717,1718],{},"onMounted","...)",[448,1721,1722,1723,1337,1725,1337,1727,1337,1729,1719],{},"Nuxt built-in composables (",[455,1724,937],{},[455,1726,1228],{},[455,1728,612],{},[455,1730,638],{},[432,1732,1734],{"id":1733},"_45-tắt-auto-import-từng-case","45. Tắt auto-import từng case?",[755,1736,1738],{"className":757,"code":1737,"language":759,"meta":760,"style":760},"\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  imports: { autoImport: false }\n});\n",[455,1739,1740,1745,1760,1778],{"__ignoreMap":760},[764,1741,1742],{"class":766,"line":767},[764,1743,1744],{"class":1608},"\u002F\u002F nuxt.config.ts\n",[764,1746,1747,1749,1752,1755,1757],{"class":766,"line":779},[764,1748,1246],{"class":1160},[764,1750,1751],{"class":1160}," default",[764,1753,1754],{"class":1071}," defineNuxtConfig",[764,1756,1075],{"class":1074},[764,1758,1759],{"class":773},"{\n",[764,1761,1762,1765,1767,1769,1772,1774,1776],{"class":766,"line":810},[764,1763,1764],{"class":791},"  imports",[764,1766,753],{"class":773},[764,1768,1088],{"class":773},[764,1770,1771],{"class":791}," autoImport",[764,1773,753],{"class":773},[764,1775,854],{"class":803},[764,1777,1211],{"class":773},[764,1779,1780,1782,1784],{"class":766,"line":835},[764,1781,1117],{"class":773},[764,1783,1120],{"class":1074},[764,1785,1123],{"class":773},[427,1787,1789],{"id":1788},"i-module-plugin","I. Module & plugin",[432,1791,1793],{"id":1792},"_46-plugin-nuxt-là-gì-khác-middleware","46. Plugin Nuxt là gì? Khác middleware?",[445,1795,1796,1803],{},[448,1797,1798,1799,1802],{},"Plugin: chạy 1 lần khi app khởi tạo, cung cấp helper (",[455,1800,1801],{},"provide",").",[448,1804,1805],{},"Middleware: chạy mỗi route navigation.",[432,1807,1809,1810,691,1813,1816],{"id":1808},"_47-clientts-và-serverts-suffix","47. ",[455,1811,1812],{},".client.ts",[455,1814,1815],{},".server.ts"," suffix?",[445,1818,1819,1825,1831],{},[448,1820,1821,1824],{},[455,1822,1823],{},"myPlugin.client.ts",": chỉ chạy client.",[448,1826,1827,1830],{},[455,1828,1829],{},"myPlugin.server.ts",": chỉ chạy server.",[448,1832,1833],{},"Không suffix: cả 2.",[432,1835,1837],{"id":1836},"_48-module-hot-phải-biết","48. Module hot phải biết?",[437,1839,1840,1337,1843,1337,1846,1337,1849,1337,1852,1337,1855,1337,1858,605],{},[455,1841,1842],{},"@nuxt\u002Fui",[455,1844,1845],{},"@pinia\u002Fnuxt",[455,1847,1848],{},"@nuxt\u002Fimage",[455,1850,1851],{},"@nuxt\u002Fcontent",[455,1853,1854],{},"@vueuse\u002Fnuxt",[455,1856,1857],{},"@nuxtjs\u002Fi18n",[455,1859,1860],{},"@nuxtjs\u002Ftailwindcss",[427,1862,1864],{"id":1863},"j-performance-deploy","J. Performance & deploy",[432,1866,1868],{"id":1867},"_49-bundle-analyzer","49. Bundle analyzer?",[755,1870,1874],{"className":1871,"code":1872,"language":1873,"meta":760,"style":760},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npx nuxt analyze\n","bash",[455,1875,1876],{"__ignoreMap":760},[764,1877,1878,1881,1884],{"class":766,"line":767},[764,1879,1880],{"class":770},"npx",[764,1882,1883],{"class":785}," nuxt",[764,1885,1886],{"class":785}," analyze\n",[437,1888,1889],{},"Mở HTML report xem module nào nặng.",[432,1891,1893],{"id":1892},"_50-lazy-load-component","50. Lazy load component?",[437,1895,1896,1897,753],{},"Prefix ",[455,1898,1899],{},"Lazy",[755,1901,1905],{"className":1902,"code":1903,"language":1904,"meta":760,"style":760},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003CLazyMyHeavyComponent v-if=\"show\" \u002F>\n","vue",[455,1906,1907],{"__ignoreMap":760},[764,1908,1909,1912,1915,1918,1920,1922,1925,1927],{"class":766,"line":767},[764,1910,1911],{"class":773},"\u003C",[764,1913,1914],{"class":791},"LazyMyHeavyComponent",[764,1916,1917],{"class":1160}," v-if",[764,1919,1255],{"class":773},[764,1921,788],{"class":773},[764,1923,1924],{"class":1074},"show",[764,1926,788],{"class":773},[764,1928,1929],{"class":773}," \u002F>\n",[437,1931,1932],{},"Component bundled riêng chunk, load on-demand.",[432,1934,1936],{"id":1935},"_51-image-optimization","51. Image optimization?",[437,1938,1939,1941,1942,1945],{},[455,1940,1848],{}," — ",[455,1943,1944],{},"\u003CNuxtImg>"," auto format (avif\u002Fwebp), srcset responsive, lazy:",[755,1947,1949],{"className":1902,"code":1948,"language":1904,"meta":760,"style":760},"\u003CNuxtImg src=\"\u002Fphoto.jpg\" width=\"800\" sizes=\"sm:100vw md:50vw\" \u002F>\n",[455,1950,1951],{"__ignoreMap":760},[764,1952,1953,1955,1958,1961,1963,1965,1968,1970,1973,1975,1977,1980,1982,1985,1987,1989,1992,1994],{"class":766,"line":767},[764,1954,1911],{"class":773},[764,1956,1957],{"class":791},"NuxtImg",[764,1959,1960],{"class":1145}," src",[764,1962,1255],{"class":773},[764,1964,788],{"class":773},[764,1966,1967],{"class":785},"\u002Fphoto.jpg",[764,1969,788],{"class":773},[764,1971,1972],{"class":1145}," width",[764,1974,1255],{"class":773},[764,1976,788],{"class":773},[764,1978,1979],{"class":785},"800",[764,1981,788],{"class":773},[764,1983,1984],{"class":1145}," sizes",[764,1986,1255],{"class":773},[764,1988,788],{"class":773},[764,1990,1991],{"class":785},"sm:100vw md:50vw",[764,1993,788],{"class":773},[764,1995,1929],{"class":773},[432,1997,1999],{"id":1998},"_52-deploy-lên-đâu","52. Deploy lên đâu?",[445,2001,2002,2008,2016,2025,2033],{},[448,2003,2004,2007],{},[451,2005,2006],{},"Vercel \u002F Netlify",": auto detect Nuxt, deploy zero-config.",[448,2009,2010,792,2013,605],{},[451,2011,2012],{},"Cloudflare Pages \u002F Workers",[455,2014,2015],{},"NITRO_PRESET=cloudflare-pages",[448,2017,2018,2021,2022,605],{},[451,2019,2020],{},"Static"," (CDN bất kỳ): ",[455,2023,2024],{},"npx nuxt generate",[448,2026,2027,792,2030,605],{},[451,2028,2029],{},"Node",[455,2031,2032],{},"node .output\u002Fserver\u002Findex.mjs",[448,2034,2035,2038],{},[451,2036,2037],{},"Docker",": build container chạy Node.",[432,2040,2042,2043,2046],{"id":2041},"_53-output-chứa-gì","53. ",[455,2044,2045],{},".output\u002F"," chứa gì?",[445,2048,2049,2055],{},[448,2050,2051,2054],{},[455,2052,2053],{},".output\u002Fserver\u002F"," — code server (cho SSR).",[448,2056,2057,2060],{},[455,2058,2059],{},".output\u002Fpublic\u002F"," — static asset (deploy CDN).",[432,2062,2064],{"id":2063},"_54-tối-ưu-cold-start-serverless","54. Tối ưu cold start serverless?",[445,2066,2067,2070,2073],{},[448,2068,2069],{},"Nitro preset tối ưu cho từng platform.",[448,2071,2072],{},"Tránh import lib nặng trong server route.",[448,2074,2075],{},"Cloudflare Workers \u002F edge runtime fast cold start.",[427,2077,2079],{"id":2078},"k-câu-trick-scenario","K. Câu trick & scenario",[432,2081,2083],{"id":2082},"_55-ssr-data-fetch-body-chứa-date-object-hydrate-sao","55. SSR data fetch — body chứa Date object, hydrate sao?",[437,2085,2086,2087,2090],{},"Payload serialize qua JSON → Date thành string. Nuxt 4 dùng ",[455,2088,2089],{},"devalue"," để preserve Date, Map, Set, ... — handle tự động.",[432,2092,2094],{"id":2093},"_56-seo-meta-dynamic","56. SEO meta dynamic?",[437,2096,1133,2097,2100],{},[455,2098,2099],{},"useSeoMeta"," với reactive value:",[755,2102,2104],{"className":757,"code":2103,"language":759,"meta":760,"style":760},"useSeoMeta({ title: () => `Post — ${data.value?.title}` });\n",[455,2105,2106],{"__ignoreMap":760},[764,2107,2108,2110,2112,2114,2117,2119,2121,2123,2126,2129,2132,2135,2137,2140,2143,2146,2149,2151,2153],{"class":766,"line":767},[764,2109,2099],{"class":1071},[764,2111,1075],{"class":1074},[764,2113,795],{"class":773},[764,2115,2116],{"class":1071}," title",[764,2118,753],{"class":773},[764,2120,1258],{"class":773},[764,2122,1261],{"class":1145},[764,2124,2125],{"class":773}," `",[764,2127,2128],{"class":785},"Post — ",[764,2130,2131],{"class":773},"${",[764,2133,2134],{"class":1074},"data",[764,2136,605],{"class":773},[764,2138,2139],{"class":1074},"value",[764,2141,2142],{"class":773},"?.",[764,2144,2145],{"class":1074},"title",[764,2147,2148],{"class":773},"}`",[764,2150,1203],{"class":773},[764,2152,1120],{"class":1074},[764,2154,1123],{"class":773},[432,2156,2158],{"id":2157},"_57-auth-flow-điển-hình","57. Auth flow điển hình?",[445,2160,2161,2164,2170,2175],{},[448,2162,2163],{},"Server middleware verify token cookie.",[448,2165,2166,2167,2169],{},"Route middleware ",[455,2168,1271],{}," redirect nếu chưa login.",[448,2171,2172,2174],{},[455,2173,1228],{}," cho user info.",[448,2176,2177,2178,2181],{},"Module ",[455,2179,2180],{},"@sidebase\u002Fnuxt-auth"," cho NextAuth-style.",[432,2183,2185,2186,2188],{"id":2184},"_58-vì-sao-tránh-ref-module-level","58. Vì sao tránh ",[455,2187,1235],{}," module-level?",[437,2190,2191,2192,2194],{},"State module shared giữa request ở SSR → request A thấy state request B. Dùng ",[455,2193,1228],{}," để scope per-request.",[432,2196,2198,2199,617],{"id":2197},"_59-khi-nào-dùng-clientonly","59. Khi nào dùng ",[455,2200,1347],{},[437,2202,2203,2204,1337,2206,2209],{},"Component dùng ",[455,2205,1359],{},[455,2207,2208],{},"document",", lib browser-only. Hoặc data từ localStorage không có ở SSR.",[432,2211,2213],{"id":2212},"_60-nuxt-4-type-safety-server-route","60. Nuxt 4 type safety server route?",[755,2215,2217],{"className":757,"code":2216,"language":759,"meta":760,"style":760},"\u002F\u002F server\u002Fapi\u002Fuser.get.ts\nexport default defineEventHandler(async (event) => {\n  return { id: 1, name: \"Alice\" };\n});\n\n\u002F\u002F app\u002Fpage.vue — type tự inferred từ handler\nconst { data } = await useFetch(\"\u002Fapi\u002Fuser\");\n\u002F\u002F data.value typed { id: number; name: string } | null\n",[455,2218,2219,2224,2249,2281,2289,2295,2301,2334],{"__ignoreMap":760},[764,2220,2221],{"class":766,"line":767},[764,2222,2223],{"class":1608},"\u002F\u002F server\u002Fapi\u002Fuser.get.ts\n",[764,2225,2226,2228,2230,2233,2235,2237,2239,2243,2245,2247],{"class":766,"line":779},[764,2227,1246],{"class":1160},[764,2229,1751],{"class":1160},[764,2231,2232],{"class":1071}," defineEventHandler",[764,2234,1075],{"class":1074},[764,2236,1146],{"class":1145},[764,2238,1282],{"class":773},[764,2240,2242],{"class":2241},"sHdIc","event",[764,2244,1120],{"class":773},[764,2246,1261],{"class":1145},[764,2248,776],{"class":773},[764,2250,2251,2254,2256,2259,2261,2264,2266,2269,2271,2273,2276,2278],{"class":766,"line":810},[764,2252,2253],{"class":1160},"  return",[764,2255,1088],{"class":773},[764,2257,2258],{"class":791}," id",[764,2260,753],{"class":773},[764,2262,2263],{"class":829}," 1",[764,2265,1085],{"class":773},[764,2267,2268],{"class":791}," name",[764,2270,753],{"class":773},[764,2272,1185],{"class":773},[764,2274,2275],{"class":785},"Alice",[764,2277,788],{"class":773},[764,2279,2280],{"class":773}," };\n",[764,2282,2283,2285,2287],{"class":766,"line":835},[764,2284,1117],{"class":773},[764,2286,1120],{"class":1074},[764,2288,1123],{"class":773},[764,2290,2291],{"class":766,"line":859},[764,2292,2294],{"emptyLinePlaceholder":2293},true,"\n",[764,2296,2298],{"class":766,"line":2297},6,[764,2299,2300],{"class":1608},"\u002F\u002F app\u002Fpage.vue — type tự inferred từ handler\n",[764,2302,2304,2306,2308,2311,2313,2316,2318,2321,2323,2325,2328,2330,2332],{"class":766,"line":2303},7,[764,2305,1404],{"class":1145},[764,2307,1088],{"class":773},[764,2309,2310],{"class":1074}," data ",[764,2312,1117],{"class":773},[764,2314,2315],{"class":773}," =",[764,2317,1161],{"class":1160},[764,2319,2320],{"class":1071}," useFetch",[764,2322,1075],{"class":1074},[764,2324,788],{"class":773},[764,2326,2327],{"class":785},"\u002Fapi\u002Fuser",[764,2329,788],{"class":773},[764,2331,1120],{"class":1074},[764,2333,1123],{"class":773},[764,2335,2337],{"class":766,"line":2336},8,[764,2338,2339],{"class":1608},"\u002F\u002F data.value typed { id: number; name: string } | null\n",[437,2341,2342],{},"Type-safe API end-to-end mà không cần OpenAPI generator.",[432,2344,2346],{"id":2345},"_61-so-sánh-nuxt-với-nextjs","61. So sánh Nuxt với Next.js?",[445,2348,2349,2352,2355,2358],{},[448,2350,2351],{},"Cả 2: SSR\u002FSSG\u002FHybrid, file routing, server route.",[448,2353,2354],{},"Nuxt: Vue, Nitro server đa platform.",[448,2356,2357],{},"Next: React, Vercel-first, RSC (React Server Components).",[448,2359,2360],{},"Cộng đồng: Next lớn hơn (ecosystem React); Nuxt gọn gàng hơn, ít boilerplate.",[432,2362,2364],{"id":2363},"_62-nuxt-tailwind-setup","62. Nuxt + Tailwind setup?",[755,2366,2368],{"className":1871,"code":2367,"language":1873,"meta":760,"style":760},"npx nuxi@latest module add tailwindcss\n",[455,2369,2370],{"__ignoreMap":760},[764,2371,2372,2374,2377,2380,2383],{"class":766,"line":767},[764,2373,1880],{"class":770},[764,2375,2376],{"class":785}," nuxi@latest",[764,2378,2379],{"class":785}," module",[764,2381,2382],{"class":785}," add",[764,2384,2385],{"class":785}," tailwindcss\n",[437,2387,2388,2389,605],{},"Auto setup, config trong ",[455,2390,2391],{},"tailwind.config.js",[432,2393,2395],{"id":2394},"_63-i18n-trong-nuxt","63. i18n trong Nuxt?",[755,2397,2399],{"className":1871,"code":2398,"language":1873,"meta":760,"style":760},"npm i @nuxtjs\u002Fi18n\n",[455,2400,2401],{"__ignoreMap":760},[764,2402,2403,2406,2409],{"class":766,"line":767},[764,2404,2405],{"class":770},"npm",[764,2407,2408],{"class":785}," i",[764,2410,2411],{"class":785}," @nuxtjs\u002Fi18n\n",[755,2413,2415],{"className":757,"code":2414,"language":759,"meta":760,"style":760},"modules: ['@nuxtjs\u002Fi18n'],\ni18n: {\n  locales: ['en', 'vi'],\n  defaultLocale: 'vi',\n}\n",[455,2416,2417,2440,2449,2479,2494],{"__ignoreMap":760},[764,2418,2419,2422,2424,2427,2430,2432,2434,2437],{"class":766,"line":767},[764,2420,2421],{"class":770},"modules",[764,2423,753],{"class":773},[764,2425,2426],{"class":1074}," [",[764,2428,2429],{"class":773},"'",[764,2431,1857],{"class":785},[764,2433,2429],{"class":773},[764,2435,2436],{"class":1074},"]",[764,2438,2439],{"class":773},",\n",[764,2441,2442,2445,2447],{"class":766,"line":779},[764,2443,2444],{"class":770},"i18n",[764,2446,753],{"class":773},[764,2448,776],{"class":773},[764,2450,2451,2454,2456,2458,2460,2463,2465,2467,2470,2473,2475,2477],{"class":766,"line":810},[764,2452,2453],{"class":770},"  locales",[764,2455,753],{"class":773},[764,2457,2426],{"class":791},[764,2459,2429],{"class":773},[764,2461,2462],{"class":785},"en",[764,2464,2429],{"class":773},[764,2466,1085],{"class":773},[764,2468,2469],{"class":773}," '",[764,2471,2472],{"class":785},"vi",[764,2474,2429],{"class":773},[764,2476,2436],{"class":791},[764,2478,2439],{"class":773},[764,2480,2481,2484,2486,2488,2490,2492],{"class":766,"line":835},[764,2482,2483],{"class":770},"  defaultLocale",[764,2485,753],{"class":773},[764,2487,2469],{"class":773},[764,2489,2472],{"class":785},[764,2491,2429],{"class":773},[764,2493,2439],{"class":773},[764,2495,2496],{"class":766,"line":859},[764,2497,862],{"class":773},[437,2499,2203,2500,1669,2503,605],{},[455,2501,2502],{},"$t('key')",[455,2504,2505],{},"useI18n()",[432,2507,2509],{"id":2508},"_64-test-nuxt-app","64. Test Nuxt app?",[437,2511,2512,2515],{},[455,2513,2514],{},"@nuxt\u002Ftest-utils"," + Vitest:",[755,2517,2519],{"className":757,"code":2518,"language":759,"meta":760,"style":760},"import { setup, $fetch } from '@nuxt\u002Ftest-utils';\n\ndescribe('app', async () => {\n  await setup({});\n  it('renders home', async () => {\n    expect(await $fetch('\u002F')).toContain('Welcome');\n  });\n});\n",[455,2520,2521,2548,2552,2577,2593,2617,2657,2666],{"__ignoreMap":760},[764,2522,2523,2526,2528,2531,2533,2535,2537,2540,2542,2544,2546],{"class":766,"line":767},[764,2524,2525],{"class":1160},"import",[764,2527,1088],{"class":773},[764,2529,2530],{"class":1074}," setup",[764,2532,1085],{"class":773},[764,2534,1164],{"class":1074},[764,2536,1203],{"class":773},[764,2538,2539],{"class":1160}," from",[764,2541,2469],{"class":773},[764,2543,2514],{"class":785},[764,2545,2429],{"class":773},[764,2547,1123],{"class":773},[764,2549,2550],{"class":766,"line":779},[764,2551,2294],{"emptyLinePlaceholder":2293},[764,2553,2554,2557,2559,2561,2564,2566,2568,2571,2573,2575],{"class":766,"line":810},[764,2555,2556],{"class":1071},"describe",[764,2558,1075],{"class":1074},[764,2560,2429],{"class":773},[764,2562,2563],{"class":785},"app",[764,2565,2429],{"class":773},[764,2567,1085],{"class":773},[764,2569,2570],{"class":1145}," async",[764,2572,1258],{"class":773},[764,2574,1261],{"class":1145},[764,2576,776],{"class":773},[764,2578,2579,2582,2584,2586,2589,2591],{"class":766,"line":835},[764,2580,2581],{"class":1160},"  await",[764,2583,2530],{"class":1071},[764,2585,1075],{"class":791},[764,2587,2588],{"class":773},"{}",[764,2590,1120],{"class":791},[764,2592,1123],{"class":773},[764,2594,2595,2598,2600,2602,2605,2607,2609,2611,2613,2615],{"class":766,"line":859},[764,2596,2597],{"class":1071},"  it",[764,2599,1075],{"class":791},[764,2601,2429],{"class":773},[764,2603,2604],{"class":785},"renders home",[764,2606,2429],{"class":773},[764,2608,1085],{"class":773},[764,2610,2570],{"class":1145},[764,2612,1258],{"class":773},[764,2614,1261],{"class":1145},[764,2616,776],{"class":773},[764,2618,2619,2622,2624,2627,2629,2631,2633,2635,2637,2639,2641,2644,2646,2648,2651,2653,2655],{"class":766,"line":2297},[764,2620,2621],{"class":1071},"    expect",[764,2623,1075],{"class":791},[764,2625,2626],{"class":1160},"await",[764,2628,1164],{"class":1071},[764,2630,1075],{"class":791},[764,2632,2429],{"class":773},[764,2634,549],{"class":785},[764,2636,2429],{"class":773},[764,2638,1297],{"class":791},[764,2640,605],{"class":773},[764,2642,2643],{"class":1071},"toContain",[764,2645,1075],{"class":791},[764,2647,2429],{"class":773},[764,2649,2650],{"class":785},"Welcome",[764,2652,2429],{"class":773},[764,2654,1120],{"class":791},[764,2656,1123],{"class":773},[764,2658,2659,2662,2664],{"class":766,"line":2303},[764,2660,2661],{"class":773},"  }",[764,2663,1120],{"class":791},[764,2665,1123],{"class":773},[764,2667,2668,2670,2672],{"class":766,"line":2336},[764,2669,1117],{"class":773},[764,2671,1120],{"class":1074},[764,2673,1123],{"class":773},[432,2675,2677],{"id":2676},"_65-migration-nuxt-3-4-bước-cụ-thể","65. Migration Nuxt 3 → 4 — bước cụ thể?",[2679,2680,2681,2685,2689,2692],"ol",{},[448,2682,2683,605],{},[455,2684,517],{},[448,2686,2687,605],{},[455,2688,521],{},[448,2690,2691],{},"Test dev server + tests.",[448,2693,2694,2695,2697],{},"Sửa ",[455,2696,937],{}," chỗ phụ thuộc stale data behavior cũ.",[2699,2700,2703,2704,2707,2708,2712,2713,2715,2716,2718],"callout",{"color":2701,"icon":2702},"success","i-lucide-rocket","🎉 ",[451,2705,2706],{},"Hoan tat section Tự học!"," Tiep theo: ",[2709,2710,2711],"a",{"href":381},"Xay dung Todo App thuc te"," — ap dung tat ca kien thuc vao project hands-on. Hoac quay lai ",[2709,2714,154],{"href":156}," de xem chu de khac, hoac ",[2709,2717,5],{"href":7}," de on rieng.",[2720,2721,2722],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":760,"searchDepth":779,"depth":779,"links":2724},[2725,2733,2748,2758,2775,2784,2793,2799,2804,2810,2819],{"id":429,"depth":779,"text":430,"children":2726},[2727,2728,2729,2730,2731,2732],{"id":434,"depth":810,"text":435},{"id":442,"depth":810,"text":443},{"id":478,"depth":810,"text":479},{"id":493,"depth":810,"text":494},{"id":511,"depth":810,"text":512},{"id":525,"depth":810,"text":526},{"id":535,"depth":779,"text":536,"children":2734},[2735,2736,2737,2739,2741,2743,2744,2746],{"id":539,"depth":810,"text":540},{"id":567,"depth":810,"text":568},{"id":584,"depth":810,"text":2738},"9. \u003CNuxtLink> khác \u003Ca> ra sao?",{"id":608,"depth":810,"text":2740},"10. useRoute vs useRouter?",{"id":634,"depth":810,"text":2742},"11. navigateTo vs router.push?",{"id":658,"depth":810,"text":659},{"id":675,"depth":810,"text":2745},"13. definePageMeta dùng làm gì?",{"id":686,"depth":810,"text":2747},"14. \u003CNuxtPage> và \u003CNuxtLayout> khác \u003CRouterView>?",{"id":711,"depth":779,"text":712,"children":2749},[2750,2751,2752,2753,2754,2756],{"id":715,"depth":810,"text":716},{"id":745,"depth":810,"text":746},{"id":865,"depth":810,"text":866},{"id":882,"depth":810,"text":883},{"id":894,"depth":810,"text":2755},"19. routeRules đặt ở đâu?",{"id":907,"depth":810,"text":2757},"20. prerender: true khác ssr: false?",{"id":929,"depth":779,"text":930,"children":2759},[2760,2762,2764,2766,2768,2770,2772,2774],{"id":933,"depth":810,"text":2761},"21. useFetch vs $fetch khác gì?",{"id":956,"depth":810,"text":2763},"22. useFetch vs useAsyncData?",{"id":977,"depth":810,"text":2765},"23. Vì sao useFetch SSR-aware?",{"id":991,"depth":810,"text":2767},"24. useFetch Nuxt 4 khác Nuxt 3?",{"id":1015,"depth":810,"text":2769},"25. lazy: true trong useFetch để làm gì?",{"id":1033,"depth":810,"text":2771},"26. pick và transform trong useFetch?",{"id":1056,"depth":810,"text":2773},"27. watch option để làm gì?",{"id":1129,"depth":810,"text":1130},{"id":1220,"depth":779,"text":1221,"children":2776},[2777,2779,2781,2782],{"id":1224,"depth":810,"text":2778},"29. useState là gì?",{"id":1302,"depth":810,"text":2780},"30. Khi nào dùng useState vs Pinia?",{"id":1319,"depth":810,"text":1320},{"id":1350,"depth":810,"text":2783},"32. \u003CClientOnly> để làm gì?",{"id":1366,"depth":779,"text":1367,"children":2785},[2786,2787,2788,2789,2790,2791,2792],{"id":1370,"depth":810,"text":1371},{"id":1377,"depth":810,"text":1378},{"id":1393,"depth":810,"text":1394},{"id":1422,"depth":810,"text":1423},{"id":1471,"depth":810,"text":1472},{"id":1546,"depth":810,"text":1547},{"id":1556,"depth":810,"text":1557},{"id":1567,"depth":779,"text":1568,"children":2794},[2795,2797,2798],{"id":1571,"depth":810,"text":2796},"40. runtimeConfig vs appConfig?",{"id":1597,"depth":810,"text":1598},{"id":1661,"depth":810,"text":1662},{"id":1678,"depth":779,"text":1679,"children":2800},[2801,2802,2803],{"id":1682,"depth":810,"text":1683},{"id":1689,"depth":810,"text":1690},{"id":1733,"depth":810,"text":1734},{"id":1788,"depth":779,"text":1789,"children":2805},[2806,2807,2809],{"id":1792,"depth":810,"text":1793},{"id":1808,"depth":810,"text":2808},"47. .client.ts và .server.ts suffix?",{"id":1836,"depth":810,"text":1837},{"id":1863,"depth":779,"text":1864,"children":2811},[2812,2813,2814,2815,2816,2818],{"id":1867,"depth":810,"text":1868},{"id":1892,"depth":810,"text":1893},{"id":1935,"depth":810,"text":1936},{"id":1998,"depth":810,"text":1999},{"id":2041,"depth":810,"text":2817},"53. .output\u002F chứa gì?",{"id":2063,"depth":810,"text":2064},{"id":2078,"depth":779,"text":2079,"children":2820},[2821,2822,2823,2824,2826,2828,2829,2830,2831,2832,2833],{"id":2082,"depth":810,"text":2083},{"id":2093,"depth":810,"text":2094},{"id":2157,"depth":810,"text":2158},{"id":2184,"depth":810,"text":2825},"58. Vì sao tránh ref module-level?",{"id":2197,"depth":810,"text":2827},"59. Khi nào dùng \u003CClientOnly>?",{"id":2212,"depth":810,"text":2213},{"id":2345,"depth":810,"text":2346},{"id":2363,"depth":810,"text":2364},{"id":2394,"depth":810,"text":2395},{"id":2508,"depth":810,"text":2509},{"id":2676,"depth":810,"text":2677},"45+ câu hỏi Nuxt 4 + Vue 3 cho dev frontend \u002F fullstack — version mới nhất.","md",null,{},{"title":307,"icon":196},{"title":422,"description":2834},"pqUrkZyJ2jXt7PwwfRIRZLP9t1_DMak7bwzdao3cLu0",[2842,2844],{"title":373,"path":374,"stem":375,"description":2843,"icon":91,"children":-1},"useFetch, useAsyncData, $fetch, state management, server API routes, Nitro engine — Nuxt 4 mới nhất.",{"title":380,"path":381,"stem":382,"description":2845,"icon":383,"children":-1},"Hướng dẫn chi tiết từng bước xây dựng Todo App hoàn chỉnh với Nuxt 4 — composables, useState, components, TypeScript, localStorage.",1783490360533]