create-plasmic-app 0.0.167 → 0.0.168

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/cpa-out/nextjs-app-codegen-js/app/dynamic/[slug]/page.jsx +5 -5
  2. package/cpa-out/nextjs-app-codegen-js/app/robots.js +24 -0
  3. package/cpa-out/nextjs-app-codegen-js/app/sitemap.js +38 -0
  4. package/cpa-out/nextjs-app-codegen-js/components/plasmic/create_plasmic_app/PlasmicDynamicPage.jsx +2 -2
  5. package/cpa-out/nextjs-app-codegen-js/components/plasmic/create_plasmic_app/PlasmicDynamicPageServer.jsx +2 -2
  6. package/cpa-out/nextjs-app-codegen-js/components/plasmic/create_plasmic_app/plasmic.css +16 -0
  7. package/cpa-out/nextjs-app-codegen-js/components/plasmic/plasmic__default_style.css +16 -0
  8. package/cpa-out/nextjs-app-codegen-js/package.json +6 -6
  9. package/cpa-out/nextjs-app-codegen-js/plasmic.json +2 -6
  10. package/cpa-out/nextjs-app-codegen-ts/app/dynamic/[slug]/page.tsx +8 -11
  11. package/cpa-out/nextjs-app-codegen-ts/app/page.tsx +4 -4
  12. package/cpa-out/nextjs-app-codegen-ts/app/robots.ts +25 -0
  13. package/cpa-out/nextjs-app-codegen-ts/app/sitemap.ts +41 -0
  14. package/cpa-out/nextjs-app-codegen-ts/components/plasmic/create_plasmic_app/PlasmicDynamicPage.tsx +2 -2
  15. package/cpa-out/nextjs-app-codegen-ts/components/plasmic/create_plasmic_app/PlasmicDynamicPageServer.tsx +7 -13
  16. package/cpa-out/nextjs-app-codegen-ts/components/plasmic/create_plasmic_app/PlasmicHomepageServer.tsx +5 -11
  17. package/cpa-out/nextjs-app-codegen-ts/components/plasmic/create_plasmic_app/plasmic.css +16 -0
  18. package/cpa-out/nextjs-app-codegen-ts/components/plasmic/plasmic__default_style.css +16 -0
  19. package/cpa-out/nextjs-app-codegen-ts/package.json +6 -6
  20. package/cpa-out/nextjs-app-codegen-ts/plasmic.json +2 -6
  21. package/cpa-out/nextjs-app-loader-js/app/robots.js +24 -0
  22. package/cpa-out/nextjs-app-loader-js/app/sitemap.js +29 -0
  23. package/cpa-out/nextjs-app-loader-js/package.json +5 -5
  24. package/cpa-out/nextjs-app-loader-ts/app/layout.tsx +1 -5
  25. package/cpa-out/nextjs-app-loader-ts/app/robots.ts +25 -0
  26. package/cpa-out/nextjs-app-loader-ts/app/sitemap.ts +30 -0
  27. package/cpa-out/nextjs-app-loader-ts/package.json +5 -5
  28. package/cpa-out/nextjs-pages-codegen-js/pages/robots.txt.js +25 -0
  29. package/cpa-out/nextjs-pages-codegen-js/pages/sitemap.xml.js +53 -0
  30. package/cpa-out/nextjs-pages-codegen-ts/pages/robots.txt.ts +27 -0
  31. package/cpa-out/nextjs-pages-codegen-ts/pages/sitemap.xml.ts +56 -0
  32. package/cpa-out/nextjs-pages-loader-js/pages/robots.txt.js +25 -0
  33. package/cpa-out/nextjs-pages-loader-js/pages/sitemap.xml.js +46 -0
  34. package/cpa-out/nextjs-pages-loader-ts/pages/robots.txt.ts +27 -0
  35. package/cpa-out/nextjs-pages-loader-ts/pages/sitemap.xml.ts +47 -0
  36. package/dist/nextjs/nextjs.js +14 -0
  37. package/dist/nextjs/templates/app-seo.d.ts +4 -0
  38. package/dist/nextjs/templates/app-seo.js +92 -0
  39. package/dist/nextjs/templates/pages-seo.d.ts +4 -0
  40. package/dist/nextjs/templates/pages-seo.js +121 -0
  41. package/package.json +2 -2
  42. package/src/nextjs/nextjs.ts +46 -0
  43. package/src/nextjs/templates/app-seo.ts +104 -0
  44. package/src/nextjs/templates/pages-seo.ts +131 -0
@@ -0,0 +1,25 @@
1
+ import type { MetadataRoute } from "next";
2
+ import { headers } from "next/headers";
3
+
4
+ // Set NEXT_PUBLIC_SITE_URL to pin the origin and keep this route static;
5
+ // otherwise it is derived per-request, which opts the route out of prerendering.
6
+ async function getSiteUrl() {
7
+ if (process.env.NEXT_PUBLIC_SITE_URL) {
8
+ return process.env.NEXT_PUBLIC_SITE_URL;
9
+ }
10
+ if (process.env.VERCEL_PROJECT_PRODUCTION_URL) {
11
+ return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`;
12
+ }
13
+ const h = await headers();
14
+ const proto = h.get("x-forwarded-proto") ?? "http";
15
+ return `${proto}://${h.get("x-forwarded-host") ?? h.get("host")}`;
16
+ }
17
+
18
+ export default async function robots(): Promise<MetadataRoute.Robots> {
19
+ const siteUrl = await getSiteUrl();
20
+
21
+ return {
22
+ rules: { userAgent: "*", allow: "/" },
23
+ sitemap: new URL("/sitemap.xml", siteUrl).toString(),
24
+ };
25
+ }
@@ -0,0 +1,30 @@
1
+ import { PLASMIC } from "@/plasmic-init";
2
+ import type { MetadataRoute } from "next";
3
+ import { headers } from "next/headers";
4
+
5
+ export const revalidate = 60;
6
+
7
+ // Set NEXT_PUBLIC_SITE_URL to pin the origin and keep this route static;
8
+ // otherwise it is derived per-request, which opts the route out of prerendering.
9
+ async function getSiteUrl() {
10
+ if (process.env.NEXT_PUBLIC_SITE_URL) {
11
+ return process.env.NEXT_PUBLIC_SITE_URL;
12
+ }
13
+ if (process.env.VERCEL_PROJECT_PRODUCTION_URL) {
14
+ return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`;
15
+ }
16
+ const h = await headers();
17
+ const proto = h.get("x-forwarded-proto") ?? "http";
18
+ return `${proto}://${h.get("x-forwarded-host") ?? h.get("host")}`;
19
+ }
20
+
21
+ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
22
+ const siteUrl = await getSiteUrl();
23
+
24
+ // fetchPages() drops pages whose path takes a param, e.g. "/blog/[slug]".
25
+ const pages = await PLASMIC.fetchPages();
26
+
27
+ return pages.map((page) => ({
28
+ url: new URL(page.path, siteUrl).toString(),
29
+ }));
30
+ }
@@ -9,17 +9,17 @@
9
9
  "lint": "eslint"
10
10
  },
11
11
  "dependencies": {
12
- "@plasmicapp/loader-nextjs": "^2.0.6",
13
- "next": "16.2.7",
14
- "react": "19.2.4",
15
- "react-dom": "19.2.4"
12
+ "@plasmicapp/loader-nextjs": "^2.0.23",
13
+ "next": "16.3.1",
14
+ "react": "19.2.8",
15
+ "react-dom": "19.2.8"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@types/node": "^20",
19
19
  "@types/react": "^19",
20
20
  "@types/react-dom": "^19",
21
21
  "eslint": "^9",
22
- "eslint-config-next": "16.2.7",
22
+ "eslint-config-next": "16.3.1",
23
23
  "typescript": "^5"
24
24
  }
25
25
  }
@@ -0,0 +1,25 @@
1
+ export const getServerSideProps = async ({ req, res }) => {
2
+ // Set NEXT_PUBLIC_SITE_URL to pin the origin;
3
+ // otherwise it is derived per-request from the request headers.
4
+ const siteUrl =
5
+ process.env.NEXT_PUBLIC_SITE_URL ??
6
+ (process.env.VERCEL_PROJECT_PRODUCTION_URL
7
+ ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
8
+ : `${req.headers["x-forwarded-proto"] ?? "http"}://${
9
+ req.headers["x-forwarded-host"] ?? req.headers.host
10
+ }`);
11
+
12
+ res.setHeader("Content-Type", "text/plain; charset=utf-8");
13
+ res.write(
14
+ `User-agent: *\nAllow: /\n\nSitemap: ${new URL(
15
+ "/sitemap.xml",
16
+ siteUrl
17
+ ).toString()}\n`
18
+ );
19
+ res.end();
20
+ return { props: {} };
21
+ };
22
+
23
+ export default function Robots() {
24
+ return null;
25
+ }
@@ -0,0 +1,53 @@
1
+ import plasmicJson from "../plasmic.json";
2
+
3
+ function escapeXml(str) {
4
+ return str
5
+ .replace(/&/g, "&amp;")
6
+ .replace(/</g, "&lt;")
7
+ .replace(/>/g, "&gt;")
8
+ .replace(/"/g, "&quot;")
9
+ .replace(/'/g, "&apos;");
10
+ }
11
+
12
+ function makeSitemapXml(urls) {
13
+ const entries = urls.map(
14
+ (url) => ` <url><loc>${escapeXml(url)}</loc></url>`
15
+ );
16
+ return `<?xml version="1.0" encoding="UTF-8"?>
17
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
18
+ ${entries.join("\n")}
19
+ </urlset>
20
+ `;
21
+ }
22
+
23
+ export const getServerSideProps = async ({ req, res }) => {
24
+ // Set NEXT_PUBLIC_SITE_URL to pin the origin;
25
+ // otherwise it is derived per-request from the request headers.
26
+ const siteUrl =
27
+ process.env.NEXT_PUBLIC_SITE_URL ??
28
+ (process.env.VERCEL_PROJECT_PRODUCTION_URL
29
+ ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
30
+ : `${req.headers["x-forwarded-proto"] ?? "http"}://${
31
+ req.headers["x-forwarded-host"] ?? req.headers.host
32
+ }`);
33
+
34
+ const urls = plasmicJson.projects
35
+ .flatMap((project) => project.components)
36
+ .flatMap((component) =>
37
+ component.componentType === "page" &&
38
+ component.path &&
39
+ !component.path.includes("[")
40
+ ? // next.config sets trailingSlash.
41
+ [new URL(component.path.replace(/\/?$/, "/"), siteUrl).toString()]
42
+ : []
43
+ );
44
+
45
+ res.setHeader("Content-Type", "application/xml; charset=utf-8");
46
+ res.write(makeSitemapXml(urls));
47
+ res.end();
48
+ return { props: {} };
49
+ };
50
+
51
+ export default function Sitemap() {
52
+ return null;
53
+ }
@@ -0,0 +1,27 @@
1
+ import type { GetServerSideProps } from "next";
2
+
3
+ export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
4
+ // Set NEXT_PUBLIC_SITE_URL to pin the origin;
5
+ // otherwise it is derived per-request from the request headers.
6
+ const siteUrl =
7
+ process.env.NEXT_PUBLIC_SITE_URL ??
8
+ (process.env.VERCEL_PROJECT_PRODUCTION_URL
9
+ ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
10
+ : `${req.headers["x-forwarded-proto"] ?? "http"}://${
11
+ req.headers["x-forwarded-host"] ?? req.headers.host
12
+ }`);
13
+
14
+ res.setHeader("Content-Type", "text/plain; charset=utf-8");
15
+ res.write(
16
+ `User-agent: *\nAllow: /\n\nSitemap: ${new URL(
17
+ "/sitemap.xml",
18
+ siteUrl
19
+ ).toString()}\n`
20
+ );
21
+ res.end();
22
+ return { props: {} };
23
+ };
24
+
25
+ export default function Robots() {
26
+ return null;
27
+ }
@@ -0,0 +1,56 @@
1
+ import type { GetServerSideProps } from "next";
2
+ import plasmicJson from "../plasmic.json";
3
+
4
+ function escapeXml(str: string) {
5
+ return str
6
+ .replace(/&/g, "&amp;")
7
+ .replace(/</g, "&lt;")
8
+ .replace(/>/g, "&gt;")
9
+ .replace(/"/g, "&quot;")
10
+ .replace(/'/g, "&apos;");
11
+ }
12
+
13
+ function makeSitemapXml(urls: string[]) {
14
+ const entries = urls.map(
15
+ (url) => ` <url><loc>${escapeXml(url)}</loc></url>`
16
+ );
17
+ return `<?xml version="1.0" encoding="UTF-8"?>
18
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
19
+ ${entries.join("\n")}
20
+ </urlset>
21
+ `;
22
+ }
23
+
24
+ export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
25
+ // Set NEXT_PUBLIC_SITE_URL to pin the origin;
26
+ // otherwise it is derived per-request from the request headers.
27
+ const siteUrl =
28
+ process.env.NEXT_PUBLIC_SITE_URL ??
29
+ (process.env.VERCEL_PROJECT_PRODUCTION_URL
30
+ ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
31
+ : `${req.headers["x-forwarded-proto"] ?? "http"}://${
32
+ req.headers["x-forwarded-host"] ?? req.headers.host
33
+ }`);
34
+
35
+ const urls = (plasmicJson.projects as {
36
+ components: { componentType: string; path?: string }[];
37
+ }[])
38
+ .flatMap((project) => project.components)
39
+ .flatMap((component) =>
40
+ component.componentType === "page" &&
41
+ component.path &&
42
+ !component.path.includes("[")
43
+ ? // next.config sets trailingSlash.
44
+ [new URL(component.path.replace(/\/?$/, "/"), siteUrl).toString()]
45
+ : []
46
+ );
47
+
48
+ res.setHeader("Content-Type", "application/xml; charset=utf-8");
49
+ res.write(makeSitemapXml(urls));
50
+ res.end();
51
+ return { props: {} };
52
+ };
53
+
54
+ export default function Sitemap() {
55
+ return null;
56
+ }
@@ -0,0 +1,25 @@
1
+ export const getServerSideProps = async ({ req, res }) => {
2
+ // Set NEXT_PUBLIC_SITE_URL to pin the origin;
3
+ // otherwise it is derived per-request from the request headers.
4
+ const siteUrl =
5
+ process.env.NEXT_PUBLIC_SITE_URL ??
6
+ (process.env.VERCEL_PROJECT_PRODUCTION_URL
7
+ ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
8
+ : `${req.headers["x-forwarded-proto"] ?? "http"}://${
9
+ req.headers["x-forwarded-host"] ?? req.headers.host
10
+ }`);
11
+
12
+ res.setHeader("Content-Type", "text/plain; charset=utf-8");
13
+ res.write(
14
+ `User-agent: *\nAllow: /\n\nSitemap: ${new URL(
15
+ "/sitemap.xml",
16
+ siteUrl
17
+ ).toString()}\n`
18
+ );
19
+ res.end();
20
+ return { props: {} };
21
+ };
22
+
23
+ export default function Robots() {
24
+ return null;
25
+ }
@@ -0,0 +1,46 @@
1
+ import { PLASMIC } from "@/plasmic-init";
2
+
3
+ function escapeXml(str) {
4
+ return str
5
+ .replace(/&/g, "&amp;")
6
+ .replace(/</g, "&lt;")
7
+ .replace(/>/g, "&gt;")
8
+ .replace(/"/g, "&quot;")
9
+ .replace(/'/g, "&apos;");
10
+ }
11
+
12
+ function makeSitemapXml(urls) {
13
+ const entries = urls.map(
14
+ (url) => ` <url><loc>${escapeXml(url)}</loc></url>`
15
+ );
16
+ return `<?xml version="1.0" encoding="UTF-8"?>
17
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
18
+ ${entries.join("\n")}
19
+ </urlset>
20
+ `;
21
+ }
22
+
23
+ export const getServerSideProps = async ({ req, res }) => {
24
+ // Set NEXT_PUBLIC_SITE_URL to pin the origin;
25
+ // otherwise it is derived per-request from the request headers.
26
+ const siteUrl =
27
+ process.env.NEXT_PUBLIC_SITE_URL ??
28
+ (process.env.VERCEL_PROJECT_PRODUCTION_URL
29
+ ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
30
+ : `${req.headers["x-forwarded-proto"] ?? "http"}://${
31
+ req.headers["x-forwarded-host"] ?? req.headers.host
32
+ }`);
33
+
34
+ // fetchPages() drops pages whose path takes a param, e.g. "/blog/[slug]".
35
+ const pages = await PLASMIC.fetchPages();
36
+ const urls = pages.map((page) => new URL(page.path, siteUrl).toString());
37
+
38
+ res.setHeader("Content-Type", "application/xml; charset=utf-8");
39
+ res.write(makeSitemapXml(urls));
40
+ res.end();
41
+ return { props: {} };
42
+ };
43
+
44
+ export default function Sitemap() {
45
+ return null;
46
+ }
@@ -0,0 +1,27 @@
1
+ import type { GetServerSideProps } from "next";
2
+
3
+ export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
4
+ // Set NEXT_PUBLIC_SITE_URL to pin the origin;
5
+ // otherwise it is derived per-request from the request headers.
6
+ const siteUrl =
7
+ process.env.NEXT_PUBLIC_SITE_URL ??
8
+ (process.env.VERCEL_PROJECT_PRODUCTION_URL
9
+ ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
10
+ : `${req.headers["x-forwarded-proto"] ?? "http"}://${
11
+ req.headers["x-forwarded-host"] ?? req.headers.host
12
+ }`);
13
+
14
+ res.setHeader("Content-Type", "text/plain; charset=utf-8");
15
+ res.write(
16
+ `User-agent: *\nAllow: /\n\nSitemap: ${new URL(
17
+ "/sitemap.xml",
18
+ siteUrl
19
+ ).toString()}\n`
20
+ );
21
+ res.end();
22
+ return { props: {} };
23
+ };
24
+
25
+ export default function Robots() {
26
+ return null;
27
+ }
@@ -0,0 +1,47 @@
1
+ import { PLASMIC } from "@/plasmic-init";
2
+ import type { GetServerSideProps } from "next";
3
+
4
+ function escapeXml(str: string) {
5
+ return str
6
+ .replace(/&/g, "&amp;")
7
+ .replace(/</g, "&lt;")
8
+ .replace(/>/g, "&gt;")
9
+ .replace(/"/g, "&quot;")
10
+ .replace(/'/g, "&apos;");
11
+ }
12
+
13
+ function makeSitemapXml(urls: string[]) {
14
+ const entries = urls.map(
15
+ (url) => ` <url><loc>${escapeXml(url)}</loc></url>`
16
+ );
17
+ return `<?xml version="1.0" encoding="UTF-8"?>
18
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
19
+ ${entries.join("\n")}
20
+ </urlset>
21
+ `;
22
+ }
23
+
24
+ export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
25
+ // Set NEXT_PUBLIC_SITE_URL to pin the origin;
26
+ // otherwise it is derived per-request from the request headers.
27
+ const siteUrl =
28
+ process.env.NEXT_PUBLIC_SITE_URL ??
29
+ (process.env.VERCEL_PROJECT_PRODUCTION_URL
30
+ ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
31
+ : `${req.headers["x-forwarded-proto"] ?? "http"}://${
32
+ req.headers["x-forwarded-host"] ?? req.headers.host
33
+ }`);
34
+
35
+ // fetchPages() drops pages whose path takes a param, e.g. "/blog/[slug]".
36
+ const pages = await PLASMIC.fetchPages();
37
+ const urls = pages.map((page) => new URL(page.path, siteUrl).toString());
38
+
39
+ res.setHeader("Content-Type", "application/xml; charset=utf-8");
40
+ res.write(makeSitemapXml(urls));
41
+ res.end();
42
+ return { props: {} };
43
+ };
44
+
45
+ export default function Sitemap() {
46
+ return null;
47
+ }
@@ -28,11 +28,13 @@ const catchall_page_1 = require("./templates/app-loader/catchall-page");
28
28
  const plasmic_host_2 = require("./templates/app-loader/plasmic-host");
29
29
  const plasmic_init_1 = require("./templates/app-loader/plasmic-init");
30
30
  const plasmic_init_client_2 = require("./templates/app-loader/plasmic-init-client");
31
+ const app_seo_1 = require("./templates/app-seo");
31
32
  const app_1 = require("./templates/pages-codegen/app");
32
33
  const plasmic_host_3 = require("./templates/pages-codegen/plasmic-host");
33
34
  const catchall_page_2 = require("./templates/pages-loader/catchall-page");
34
35
  const plasmic_host_4 = require("./templates/pages-loader/plasmic-host");
35
36
  const plasmic_init_2 = require("./templates/pages-loader/plasmic-init");
37
+ const pages_seo_1 = require("./templates/pages-seo");
36
38
  exports.nextjsStrategy = {
37
39
  create: (args) => __awaiter(void 0, void 0, void 0, function* () {
38
40
  var _a;
@@ -124,6 +126,8 @@ function generateFilesAppDir(args) {
124
126
  const { projectPath, scheme, jsOrTs, projectId, projectApiToken } = args;
125
127
  // Delete existing pages
126
128
  (0, file_utils_1.deleteGlob)(path_1.default.join(projectPath, "app", "page.*"));
129
+ // ./app/robots.ts
130
+ yield fs_1.promises.writeFile(path_1.default.join(projectPath, "app", `robots.${jsOrTs}`), (0, app_seo_1.makeRobots_app)(jsOrTs));
127
131
  if (scheme === "loader") {
128
132
  // ./plasmic-init.ts
129
133
  yield fs_1.promises.writeFile(path_1.default.join(projectPath, `plasmic-init.${jsOrTs}`), (0, plasmic_init_1.makePlasmicInit_app_loader)(projectId, (0, lang_utils_1.ensure)(projectApiToken, "Missing projectApiToken")));
@@ -135,6 +139,8 @@ function generateFilesAppDir(args) {
135
139
  // ./app/[[...catchall]]/page.tsx
136
140
  yield fs_1.promises.mkdir(path_1.default.join(projectPath, "app", "[[...catchall]]"));
137
141
  yield fs_1.promises.writeFile(path_1.default.join(projectPath, "app", "[[...catchall]]", `page.${jsOrTs}x`), (0, catchall_page_1.makeCatchallPage_app_loader)(jsOrTs));
142
+ // ./app/sitemap.ts
143
+ yield fs_1.promises.writeFile(path_1.default.join(projectPath, "app", `sitemap.${jsOrTs}`), (0, app_seo_1.makeSitemap_app_loader)(jsOrTs));
138
144
  }
139
145
  else {
140
146
  // ./plasmic-init-client.tsx
@@ -151,6 +157,8 @@ function generateFilesAppDir(args) {
151
157
  projectApiToken,
152
158
  projectPath,
153
159
  });
160
+ // ./app/sitemap.ts
161
+ yield fs_1.promises.writeFile(path_1.default.join(projectPath, "app", `sitemap.${jsOrTs}`), (0, app_seo_1.makeSitemap_app_codegen)(jsOrTs));
154
162
  // Read plasmic.json so we can wire each top-level project's plasmic.css
155
163
  // import directly into the root layout template.
156
164
  const config = yield (0, file_utils_1.getPlasmicConfig)(projectPath, "nextjs", scheme);
@@ -177,6 +185,8 @@ function generateFilesPagesDir(args) {
177
185
  const { projectPath, scheme, jsOrTs, projectId, projectApiToken } = args;
178
186
  // Delete existing pages
179
187
  (0, file_utils_1.deleteGlob)(path_1.default.join(projectPath, "pages", "*.*"));
188
+ // ./pages/robots.txt.ts
189
+ yield fs_1.promises.writeFile(path_1.default.join(projectPath, "pages", `robots.txt.${jsOrTs}`), (0, pages_seo_1.makeRobots_pages)(jsOrTs));
180
190
  if (scheme === "loader") {
181
191
  // ./plasmic-init.ts
182
192
  yield fs_1.promises.writeFile(path_1.default.join(projectPath, `plasmic-init.${jsOrTs}`), (0, plasmic_init_2.makePlasmicInit_pages_loader)(projectId, (0, lang_utils_1.ensure)(projectApiToken, "Missing projectApiToken")));
@@ -184,6 +194,8 @@ function generateFilesPagesDir(args) {
184
194
  yield fs_1.promises.writeFile(path_1.default.join(projectPath, "pages", `plasmic-host.${jsOrTs}x`), (0, plasmic_host_4.makePlasmicHostPage_pages_loader)());
185
195
  // ./pages/[[...catchall]].tsx
186
196
  yield fs_1.promises.writeFile(path_1.default.join(projectPath, "pages", `[[...catchall]].${jsOrTs}x`), (0, catchall_page_2.makeCatchallPage_pages_loader)(jsOrTs));
197
+ // ./pages/sitemap.xml.ts
198
+ yield fs_1.promises.writeFile(path_1.default.join(projectPath, "pages", `sitemap.xml.${jsOrTs}`), (0, pages_seo_1.makeSitemap_pages_loader)(jsOrTs));
187
199
  }
188
200
  else {
189
201
  // ./pages/plasmic-host.tsx
@@ -197,6 +209,8 @@ function generateFilesPagesDir(args) {
197
209
  projectApiToken,
198
210
  projectPath,
199
211
  });
212
+ // ./pages/sitemap.xml.ts
213
+ yield fs_1.promises.writeFile(path_1.default.join(projectPath, "pages", `sitemap.xml.${jsOrTs}`), (0, pages_seo_1.makeSitemap_pages_codegen)(jsOrTs));
200
214
  // Read plasmic.json so we can wire each top-level project's plasmic.css
201
215
  // import directly into the _app template.
202
216
  const config = yield (0, file_utils_1.getPlasmicConfig)(projectPath, "nextjs", scheme);
@@ -0,0 +1,4 @@
1
+ import { JsOrTs } from "../../utils/types";
2
+ export declare function makeSitemap_app_loader(jsOrTs: JsOrTs): string;
3
+ export declare function makeSitemap_app_codegen(jsOrTs: JsOrTs): string;
4
+ export declare function makeRobots_app(jsOrTs: JsOrTs): string;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeRobots_app = exports.makeSitemap_app_codegen = exports.makeSitemap_app_loader = void 0;
4
+ const file_utils_1 = require("../../utils/file-utils");
5
+ const getSiteUrl = `// Set NEXT_PUBLIC_SITE_URL to pin the origin and keep this route static;
6
+ // otherwise it is derived per-request, which opts the route out of prerendering.
7
+ async function getSiteUrl() {
8
+ if (process.env.NEXT_PUBLIC_SITE_URL) {
9
+ return process.env.NEXT_PUBLIC_SITE_URL;
10
+ }
11
+ if (process.env.VERCEL_PROJECT_PRODUCTION_URL) {
12
+ return \`https://\${process.env.VERCEL_PROJECT_PRODUCTION_URL}\`;
13
+ }
14
+ const h = await headers();
15
+ const proto = h.get("x-forwarded-proto") ?? "http";
16
+ return \`\${proto}://\${h.get("x-forwarded-host") ?? h.get("host")}\`;
17
+ }`;
18
+ function makeHeader(jsOrTs) {
19
+ return `${(0, file_utils_1.ifTs)(jsOrTs, `import type { MetadataRoute } from "next";\n`)}import { headers } from "next/headers";\n`;
20
+ }
21
+ function makeSignature(jsOrTs) {
22
+ return `export default async function sitemap()${(0, file_utils_1.ifTs)(jsOrTs, ": Promise<MetadataRoute.Sitemap>")} {`;
23
+ }
24
+ function makeSitemap_app_loader(jsOrTs) {
25
+ return `import { PLASMIC } from "@/plasmic-init";
26
+ ${makeHeader(jsOrTs)}
27
+ export const revalidate = 60;
28
+
29
+ ${getSiteUrl}
30
+
31
+ ${makeSignature(jsOrTs)}
32
+ const siteUrl = await getSiteUrl();
33
+
34
+ // fetchPages() drops pages whose path takes a param, e.g. "/blog/[slug]".
35
+ const pages = await PLASMIC.fetchPages();
36
+
37
+ return pages.map((page) => ({
38
+ url: new URL(page.path, siteUrl).toString(),
39
+ }));
40
+ }
41
+ `;
42
+ }
43
+ exports.makeSitemap_app_loader = makeSitemap_app_loader;
44
+ function makeSitemap_app_codegen(jsOrTs) {
45
+ const projects = jsOrTs === "ts"
46
+ ? `(plasmicJson.projects as {
47
+ components: { componentType: string; path?: string }[];
48
+ }[])`
49
+ : "plasmicJson.projects";
50
+ return `${makeHeader(jsOrTs)}import plasmicJson from "../plasmic.json";
51
+
52
+ ${getSiteUrl}
53
+
54
+ ${makeSignature(jsOrTs)}
55
+ const siteUrl = await getSiteUrl();
56
+
57
+ return ${projects}
58
+ .flatMap((project) => project.components)
59
+ .flatMap((component) =>
60
+ component.componentType === "page" &&
61
+ component.path &&
62
+ !component.path.includes("[")
63
+ ? [
64
+ {
65
+ // next.config sets trailingSlash.
66
+ url: new URL(
67
+ component.path.replace(/\\/?$/, "/"),
68
+ siteUrl
69
+ ).toString(),
70
+ },
71
+ ]
72
+ : []
73
+ );
74
+ }
75
+ `;
76
+ }
77
+ exports.makeSitemap_app_codegen = makeSitemap_app_codegen;
78
+ function makeRobots_app(jsOrTs) {
79
+ return `${makeHeader(jsOrTs)}
80
+ ${getSiteUrl}
81
+
82
+ export default async function robots()${(0, file_utils_1.ifTs)(jsOrTs, ": Promise<MetadataRoute.Robots>")} {
83
+ const siteUrl = await getSiteUrl();
84
+
85
+ return {
86
+ rules: { userAgent: "*", allow: "/" },
87
+ sitemap: new URL("/sitemap.xml", siteUrl).toString(),
88
+ };
89
+ }
90
+ `;
91
+ }
92
+ exports.makeRobots_app = makeRobots_app;
@@ -0,0 +1,4 @@
1
+ import { JsOrTs } from "../../utils/types";
2
+ export declare function makeSitemap_pages_loader(jsOrTs: JsOrTs): string;
3
+ export declare function makeSitemap_pages_codegen(jsOrTs: JsOrTs): string;
4
+ export declare function makeRobots_pages(jsOrTs: JsOrTs): string;