BTST

Breaking Changes

Migration guides for upgrading between major versions

This page documents breaking changes between major versions and provides migration guides.


v2 → v3: Declarative routes and the pageComponents contract

BTST v3 adopts the declarative defineRoute / defineRoutes helpers from @btst/yar 1.3+ for all plugin routes, and stabilizes page component identity across re-renders (no more subtree remounts or Suspense re-triggers on parent renders).

The only consumer-facing change is the props passed to pageComponents overrides on parameterized routes. Overrides for routes without params, and all other plugin config, are unchanged.

pageComponents overrides now receive the route context

Overrides for parameterized routes used to receive specific named props (e.g. slug, boardId, conversationId). They now receive the route context — { params } — instead:

blogClientPlugin({
  // ... other config
  pageComponents: {
    posts: MyCustomPostsPage,          // unchanged (no params)
-   post: ({ slug }) => <MyCustomPostPage slug={slug} />,
+   post: ({ params }) => <MyCustomPostPage slug={params.slug} />,
-   tag: ({ tagSlug }) => <MyCustomTagPage tagSlug={tagSlug} />,
+   tag: ({ params }) => <MyCustomTagPage tagSlug={params.tagSlug} />,
  },
})

Renamed props per plugin:

PluginOverrideOld propsNew props
Blogpost, editPost{ slug }{ params: { slug } }
Blogtag{ tagSlug }{ params: { tagSlug } }
CMScontentList, newContent{ typeSlug }{ params: { typeSlug } }
CMSeditContent{ typeSlug, id }{ params: { typeSlug, id } }
Form BuildereditForm{ id }{ params: { id } }
Form Buildersubmissions{ formId }{ params: { id } }
UI BuildereditPage{ id }{ params: { id } }
Kanbanboard{ boardId }{ params: { boardId } }
AI ChatchatConversation{ conversationId }{ params: { id } }

createRoute is still exported and fully supported, but plugin routes are simpler with defineRoute:

- todos: createRoute("/todos", () => ({
-   PageComponent: TodosListPage,
-   loader: todosLoader(config),
-   meta: createTodosMeta(config, "/todos"),
- })),
+ todos: defineRoute("/todos", {
+   page: TodosListPage,
+   loader: todosLoader(config),
+   meta: createTodosMeta(config, "/todos"),
+ }),

defineRoute, defineRoutes, and the RouteContext / RouteDef types are re-exported from @btst/stack/plugins/client.


v1 → v2: Rebranding to BTST

BTST v2 introduces a rebranding from "Better Stack" to "BTST". This guide covers all the changes you need to make to upgrade your project.

This is a breaking change that requires updates to imports, function names, and file references. The functionality remains the same.

Summary of Changes

v1 (Better Stack)v2 (BTST)
betterStack()stack()
betterStackClient()stackClient()
BetterStackProviderStackProvider
useBetterStackuseStack
BetterStackAttributionStackAttribution
better-stack.tsstack.ts
better-stack-client.tsxstack-client.tsx
"Powered by Better Stack""Powered by BTST"

Migration Steps

Update Package

Update your @btst/stack package to v2:

npm install @btst/stack@latest
# or
pnpm add @btst/stack@latest

Rename Backend Setup Function

Update your backend configuration file (commonly lib/better-stack.tslib/stack.ts):

- import { betterStack } from "@btst/stack";
+ import { stack } from "@btst/stack";

- export const { api, clientConfig, generateSitemap } = betterStack({
+ export const { api, clientConfig, generateSitemap } = stack({
    // ... your configuration
  });

Rename Client Setup Function

Update your client configuration file (commonly lib/better-stack-client.tsxlib/stack-client.tsx):

- import { betterStackClient } from "@btst/stack/client";
+ import { stackClient } from "@btst/stack/client";

- export const { PluginPages, routes, loaders, metas } = betterStackClient({
+ export const { PluginPages, routes, loaders, metas } = stackClient({
    // ... your configuration
  });

Update Provider Component

If you're using the provider component directly:

- import { BetterStackProvider } from "@btst/stack/client";
+ import { StackProvider } from "@btst/stack/client";

function App() {
  return (
-   <BetterStackProvider overrides={overrides}>
+   <StackProvider overrides={overrides}>
      {children}
-   </BetterStackProvider>
+   </StackProvider>
  );
}

Update Hook Imports

If you're using the context hook directly:

- import { useBetterStack } from "@btst/stack/client";
+ import { useStack } from "@btst/stack/client";

function MyComponent() {
-   const context = useBetterStack();
+   const context = useStack();
    // ...
}

Update Attribution Component

If you're using the attribution component:

- import { BetterStackAttribution } from "@workspace/ui/components/better-stack-attribution";
+ import { StackAttribution } from "@workspace/ui/components/stack-attribution";

- <BetterStackAttribution />
+ <StackAttribution />

Update File Imports

Update any imports that reference the old filenames:

- import { api } from "@/lib/better-stack";
+ import { api } from "@/lib/stack";

- import { PluginPages } from "@/lib/better-stack-client";
+ import { PluginPages } from "@/lib/stack-client";

For consistency, rename your configuration files:

# Backend config
mv lib/better-stack.ts lib/stack.ts

# Client config  
mv lib/better-stack-client.tsx lib/stack-client.tsx

# Auth config (if applicable)
mv lib/better-stack-auth.ts lib/stack-auth.ts

Find and Replace

You can use these find-and-replace patterns to quickly update your codebase:

FindReplace
betterStack(stack(
betterStackClient(stackClient(
BetterStackProviderStackProvider
useBetterStackuseStack
BetterStackAttributionStackAttribution
better-stack-attributionstack-attribution
from "@/lib/better-stack"from "@/lib/stack"
from "@/lib/better-stack-client"from "@/lib/stack-client"
from "./better-stack"from "./stack"
from "./better-stack-client"from "./stack-client"

TypeScript Types

The following types have been renamed:

- import type { BetterStackContext } from "@btst/stack";
+ import type { StackContext } from "@btst/stack";

Localization Strings

If you've customized localization, update any references:

- "Powered by Better Stack"
+ "Powered by BTST"

No Functional Changes

All plugin functionality, APIs, database schemas, and component behavior remain unchanged. This is purely a naming/branding update.

The following are unchanged:

  • All plugin configurations and options
  • Database schemas and adapters
  • API endpoints and routes
  • Component props and behavior
  • Hook return values and options
  • SSR, meta tags, and sitemap generation

Need Help?

If you encounter any issues during migration, please open an issue on GitHub.