Skip to content

Commit

Permalink
initial commit - first working version
Browse files Browse the repository at this point in the history
  • Loading branch information
madaxen86 committed Nov 1, 2024
1 parent d7c936b commit 8d1f6e2
Show file tree
Hide file tree
Showing 38 changed files with 949 additions and 1,032 deletions.
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"baseBranch": "master",
"updateInternalDependencies": "patch",
"ignore": []
}
5 changes: 5 additions & 0 deletions .changeset/fair-cobras-matter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'solid-start-typesafe-routes-plugin': minor
---

intial working version
5 changes: 0 additions & 5 deletions .changeset/friendly-otters-complain.md

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ tsup.config.bundled_*.{m,c,}s

dev/public/*.xml

.routes
159 changes: 59 additions & 100 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,134 +1,93 @@
<p>
<img width='100%' src='https://assets.solidjs.com/banner?type=solid-start-sitemap&background=tiles&project=%20' alt='solid-start-sitemap'>
<img width='100%' src='https://assets.solidjs.com/banner?type=solid-start-sitemap&background=tiles&project=%20' alt='solid-start-typesafe-routes-plugin'>
</p>

# solid-start-sitemap
# solid-start-typesafe-routes-plugin

[![pnpm](https://img.shields.io/badge/maintained%20with-pnpm-cc00ff.svg?style=for-the-badge&logo=pnpm)](https://pnpm.io/)

This packages enables to build a sitemap of a solid-start-app.
Currently only file routes are available automatically.
The package will grab the route definitions from `vinxi/routes`.
Dynamic routes have are formatted like `/posts/:postId` or for the catch all routes `pages/*slug`.
This package is build on top of [sitemap.js](https://github.com/ekalinin/sitemap.js).
This plugin for solid-start will create a route manifest which provides type-safe routes based on the file-routing.

## Installation

```bash
npm i solid-start-sitemap
# or
yarn add solid-start-sitemap
# or
pnpm add solid-start-sitemap
npm i solid-start-typesafe-routes-plugin
```

## Usage

Generate a sitemap with one of the following options and add this entry to your `robots.txt` in the public directory

```bash
yarn add solid-start-typesafe-routes-plugin
```
User-agent: *
Allow: /
###### add the following line ######
Sitemap: https://www.example.com/sitemap.xml

```bash
pnpm add solid-start-typesafe-routes-plugin
```

### Options

| PROP | TYPE | EXAMPLE | DESCRIPTION |
| ------------------ | --------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| hostname | string | 'https://example.com' | Required: Basedomain of your app. |
| pubDir | string | 'public' | Defaults to 'public'. Path to public directory where the public assets are stored and the XML(s) will be saved to. The plugin will get this automatically from the app config. |
| ingoreRoutes | string[] | ['/posts/archive','/posts/archive/:postId'] | array of routes which should be excluded from the |
| replaceRouteParams | Record<string,(number\|string)[]> | {':postId':[1,2,3]} | Object which provides all params for the dynamic routes. Note that the params should have a unique name. So instead of `/posts/[id]` and `/products/[id]` you may rename them to `/posts/[postId]` and `/products/[productId]` or you may use the option `dynamicRoutes`. If you don't pass any params all dynamic routes will be ignored. Otherwise provide all params for dynamic routes which are not ignored with `ingoreRoutes` |
| dynamicRoutes | string[] | ['posts/1','/posts/2','/posts/3'] | array of custom routes to add to the sitemap. Can be used to add dynamic routes for more complex use cases |
| limit | number | 45000 | Maximum number if urls in one sitemap. If provided will generate multiple XML(s) and also create a index sitemap which references all sitemap files. |

### Generate a static sitemap during build
## Usage

For a static site with static routes or dynamic routes with fixed amount of params add the plugin to the `app.config.ts`.
It will add a `sitemap.xml` or if you pass
### Add the plugin to your `app.config.ts`

```tsx
//app.config.ts
import { defineConfig } from '@solidjs/start/config';
import { SolidStartSiteMapPlugin } from 'solid-start-sitemap';
```ts
interface PluginProps {
routeDir: string; //default: 'src/routes'
}
```

export default defineConfig({
```ts
import { SolidStartTypesafeRouterPlugin } from 'solid-start-typesafe-routes-plugin';
defineConfig({
vite: {
plugins: [
SolidStartSiteMapPlugin({
hostname: 'https://example.com',
replaceRouteParams: {
':postId': [1, 2, 3],
},
limit: 5000,
}),
],
plugins: [SolidStartTypesafeRouterPlugin()],
},
});
```

### Generate dynamic sitemap
The plugin will create an `index.js` and `index.d.ts`the in `src/RouteManifest`.

Layouts will be ignored.

The most common use case will probably be to create a sitemap dynamically either periodically (e.g. every day / every sunday, ...) or based on changes of data (e.g. new post).
Here are a few examples how to achieve this.
Updates automatically on

Add an API route which generates a new sitemap when you call it.
You can use a cronjob to re-generate periodically or if using a cms you can also use a webbhook as a trigger e.g. every time a new post is published.
1. `pnpm build`
2. `pnpm dev` on startup of the dev server and when a file is `created/moved/deleted` in the `src/routes` directory

Assuming this routes

```
src
└─routes
│ index.tsx
│ about.tsx
└─posts
│ [slug].tsx
└───multiple
│ │
│ └───[first]
│ │
│ └─[second]
│ [third].tsx
│ add.tsx
└───auth(layout)
[userId].tsx
```

You can get the routes like

```ts
// FIRST we'll create a reusable function

// ./src/lib/sitemap.ts
import { createSitemap } from 'solid-start-sitemap';
import { isServer } from 'solid-js/web';

export const generateSitemap = async () => {
if (!isServer) throw new Error("This function may only be called on the server");
//fetch all postIDs from DB / cms
const postsIDs = await getPostIDs();

await createSitemap({
hostname:'https://example.com'
replaceRouteParams: {
':postId': postIDs,
},
limit: 5000,
});
}
import { Routes } from '~/RouteManifest';

//Now we can call this e.g. every time a new post is created
// ./src/queries/posts/create.tsx
import { generateSitemap } from '~/lib/sitemap';

export async function createPost(data) {
try {
await db.create("post", data)
} catch (err) {
//handle error
}
generateSitemap().catch() //no need to await it - ignore errors
}
Routes().index; // => '/'
Routes().about.index; // => '/about'

// or create an API which can be called periodically by a cronjob or by a webbhok if you use a cms.
// ./src/routes/api/sitemap.ts
import { generateSitemap } from '~/lib/sitemap';
Routes().posts.slug('hello-world').index; // => '/posts/hello-world'

export async function GET() {
//protect the route e.g.
const token = await getAuthToken()
if (!token || token !== process.env.SITEMAP_TOKEN) return new Response('Not Authorized',{status:401})
Routes().multiple.first('a').second('b').third('c').index; // => '/multiple/a/b/c'
Routes().multiple.first('a').second('b').third('c').add.index; // => '/multiple/a/b/c/add'

try {
await generateSitemap()
return new Response('Sitemap generated successfully')
} catch (err) {
console.log(err);
return new Response(e instanceof Error ? e.message : JSON.stringify(e), { status: 500 });
}
Routes().auth.userId('xyz').index; // => '/auth/xyz'

}
// Pass searchparams to routes
Routes({ q: 'apples' }).index; // => '/?q=apples'
```
34 changes: 9 additions & 25 deletions dev/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,27 @@
import { defineConfig } from '@solidjs/start/config';
import path from 'path';
import { fileURLToPath } from 'url';
import RouteManifestPlugin from './src/TSFileRouterPlugin';

import Plugin from '../src/plugin';
const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
const __dirname = path.dirname(__filename); // get the name of the directory

const app = defineConfig({
ssr: false,
vite: {
resolve: {
alias: {
'@src': path.resolve(__dirname, '../src'),
'@plugin': path.resolve(__dirname, '../src/plugin'),
},
},
plugins: [
RouteManifestPlugin(),
Plugin({
hostname: 'http://localhost:3000',
replaceRouteParams: {
':slug': ['solid', 'solid-start', 'hello'],
':first': ['a', 'b', 'c'],
':second': ['1', '2', '3'],
':third': ['x', 'y'],
},
limit: 5000,
}),
],
optimizeDeps: {
include: ['unenv'],
},
},
server: {
experimental: {
openAPI: true,
},
alias: {
consola: 'consola',
},
optimizeDeps: {},
plugins: [Plugin()],
// build: {
// rollupOptions: {
// external: ['RouteManifest'],
// },
// },
},
});

Expand Down
2 changes: 0 additions & 2 deletions dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
"dependencies": {
"@solidjs/router": "^0.14.7",
"@solidjs/start": "^1.0.8",
"@tanstack/router-cli": "^1.74.2",
"@tanstack/router-vite-plugin": "^1.76.4",
"autoprefixer": "^10.4.19",
"consola": "^3.2.3",
"postcss": "^8.4.38",
Expand Down
Loading

0 comments on commit 8d1f6e2

Please sign in to comment.