Skip to content

Commit

Permalink
feat: binary for generate sitemap on build time (#7)
Browse files Browse the repository at this point in the history
* feat: binary for generate sitemap on build time

* add docs and fixed routeModules in runtime

* 1.2.2-canary.0

* add type to docs
  • Loading branch information
fedeya authored Mar 16, 2023
1 parent 40273a2 commit 5036314
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 6 deletions.
38 changes: 35 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@

### Features

- Generate Sitemap in Runtime
- Runtime Generation
- Build time Generation (Experimental)
- Handle Static Optional Paths

## Installation
Expand All @@ -27,11 +28,13 @@ npm i remix-sitemap
```

## Usage
For generate the sitemap we have 2 ways.
### 1. Runtime Generation
```ts
// entry.server.tsx
import { createSitemapGenerator } from 'remix-sitemap';

// setup the generator
// Step 1. setup the generator
const { isSitemapUrl, sitemap } = createSitemapGenerator({
siteUrl: 'https://example.com'
})
Expand All @@ -42,7 +45,7 @@ export default async function handleRequest(
responseHeaders: Headers,
remixContext: EntryContext
) {
//
// Step 2. add the sitemap response
if (isSitemapUrl(request))
return await sitemap(request, remixContext);

Expand All @@ -58,6 +61,31 @@ export default async function handleRequest(
});
}
```
### 2. Build time Generation (Experimental)
> Right now this doesn't work with all server build targets like Cloudflare
Create a `remix-sitemap.config.js` file at the project root
```ts
// remix-sitemap.config.js

/** @type {import('remix-sitemap').RemixSitemapConfig} */
module.exports = {
siteUrl: 'https://example.com',
// configure other things here
}
```
Add a script using `remix-sitemap` to `package.json` to run after build.

For example if you are using `npm-run-all`
```json
{
"scripts": {
"build": "npm-run-all build:*",
"build:remix": "remix build",
"build:sitemap": "remix-sitemap"
}
}
```

## Config
This library is a little inspired in [next-sitemap](https://www.npmjs.com/package/next-sitemap) so the config is pretty much the same
Expand All @@ -71,11 +99,15 @@ This library is a little inspired in [next-sitemap](https://www.npmjs.com/packag
| sitemapBaseFileName (optional) | The name of the generated sitemap file before the file extension. Default `"sitemap"` |
| optionalSegments (optional) | possible values of optional segments |
| alternateRefs (optional) | multi language support by unique url. Default `[]` |
| sourceDir | The build directory. Default `"build"` |
| outDir | The directory to create the sitemaps files. Default `"public"` |



---

## Generate Sitemap for Dynamic Routes
> If you are using build time generation, the request in `generateEntries` will be empty
```ts
// app/routes/posts.$slug.tsx
import type { SitemapHandle } from 'remix-sitemap';
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"name": "remix-sitemap",
"version": "1.2.1",
"version": "1.2.2-canary.0",
"private": false,
"bin": {
"remix-sitemap": "./dist/bin/index.js"
},
"main": "dist/index.js",
"scripts": {
"build": "tsc",
Expand Down
72 changes: 72 additions & 0 deletions src/bin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env node
import path from 'path';
import type { RemixSitemapConfig } from '../lib/types';
import type { EntryContext } from '@remix-run/server-runtime';
import { getSitemap } from '../sitemap';
import fs from 'fs/promises';

const dir = process.cwd();

type RoutesManifest = EntryContext['manifest']['routes'];

type RouteModules = EntryContext['routeModules'];

const getAllRouteModules = (routes: RoutesManifest) => {
const modules: RouteModules = {};

Object.keys(routes).forEach(route => {
const routeManifest = routes[route];

modules[routeManifest.id] =
routeManifest.module as unknown as RouteModules[string];
});

return modules;
};

async function main() {
const config = require(path.join(
dir,
'remix-sitemap.config.js'
)) as RemixSitemapConfig;

const defaultConfig = {
...config,
autoLastmod: config.autoLastmod ?? true,
changefreq: config.changefreq ?? 'daily',
priority: config.priority ?? 0.7,
sitemapBaseFileName: config.sitemapBaseFileName ?? 'sitemap',
sourceDir: config.sourceDir ?? 'build',
outDir: config.outDir ?? 'public'
};

const buildPath = path.join(dir, defaultConfig.sourceDir);

const build = require(buildPath);

const modules = getAllRouteModules(build.routes);

const sitemap = await getSitemap({
config: defaultConfig,
context: {
routeModules: modules,
manifest: {
routes: build.routes
}
} as any,
request: {} as any
});

await fs.writeFile(
path.join(
dir,
defaultConfig.outDir,
`${defaultConfig.sitemapBaseFileName}.xml`
),
sitemap
);

console.log('sitemap generated successfully :D');
}

main();
4 changes: 4 additions & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export interface RemixSitemapConfig {

optionalSegments?: Record<string, string[]>;

sourceDir?: string;

outDir?: string;

/**
* Headers to be added to the sitemap response.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/utils/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Handle, RemixSitemapConfig, SitemapHandle } from '../lib/types';
export function getRouteData(route: string, context: EntryContext) {
const manifest = context.manifest.routes[route];

const module = context.routeModules[route];
const module = context.routeModules[manifest.id];

const handle: SitemapHandle = module?.handle || {};

Expand Down
2 changes: 1 addition & 1 deletion src/utils/xml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export const getUrlXml = (entry: SitemapEntry) => {
...(entry.videos || []).map(getVideo)
].filter(truthy);

return xml({ url }, { indent: ' ' });
return xml({ url });
};

export type GetEntryXmlParams = {
Expand Down

0 comments on commit 5036314

Please sign in to comment.