Skip to content

feat: Inline onboarding product options syntax #13361

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 30 additions & 6 deletions docs/platforms/apple/common/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ To capture all errors, initialize the SDK as soon as possible, such as in your `

<PlatformSection notSupported={["apple.tvos", "apple.watchos", "apple.visionos"]}>

```swift {tabTitle:Swift} {"onboardingOptions": {"performance": "13-16", "profiling": "17-21"}}
```swift {tabTitle:Swift}
import Sentry

func application(_ application: UIApplication,
Expand All @@ -101,21 +101,25 @@ func application(_ application: UIApplication,
// For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
options.sendDefaultPii = true

// ___PRODUCT_OPTION_START___ performance
// Set tracesSampleRate to 1 to capture 100% of transactions for performance monitoring.
// We recommend adjusting this value in production.
options.tracesSampleRate = 1
// ___PRODUCT_OPTION_END___ performance

// ___PRODUCT_OPTION_START___ profiling
options.configureProfiling = {
$0.lifecycle = .trace
$0.sessionSampleRate = 1
}
// ___PRODUCT_OPTION_END___ profiling
}

return true
}
```

```objc {tabTitle:Objective-C} {"onboardingOptions": {"performance": "12-15", "profiling": "16-20"}}
```objc {tabTitle:Objective-C}
@import Sentry;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
Expand All @@ -128,21 +132,25 @@ func application(_ application: UIApplication,
// For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
options.sendDefaultPii = YES

// ___PRODUCT_OPTION_START___ performance
// Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
// We recommend adjusting this value in production.
options.tracesSampleRate = @1.f;
// ___PRODUCT_OPTION_END___ performance

// ___PRODUCT_OPTION_START___ profiling
options.configureProfiling = ^(SentryProfileOptions *profiling) {
profiling.lifecycle = SentryProfileLifecycleTrace;
profiling.sessionSampleRate = 1.f;
};
// ___PRODUCT_OPTION_END___ profiling
}];

return YES;
}
```

```swift {tabTitle:SwiftUI with App conformer} {"onboardingOptions": {"performance": "13-16", "profiling": "17-21"}}
```swift {tabTitle:SwiftUI with App conformer}
import Sentry

@main
Expand All @@ -156,14 +164,18 @@ struct SwiftUIApp: App {
// For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
options.sendDefaultPii = true

// ___PRODUCT_OPTION_START___ performance
// Set tracesSampleRate to 1 to capture 100% of transactions for performance monitoring.
// We recommend adjusting this value in production.
options.tracesSampleRate = 1
// ___PRODUCT_OPTION_END___ performance

// ___PRODUCT_OPTION_START___ profiling
options.configureProfiling = {
$0.lifecycle = .trace
$0.sessionSampleRate = 1
}
// ___PRODUCT_OPTION_END___ profiling
}
}
}
Expand All @@ -172,7 +184,7 @@ struct SwiftUIApp: App {

<PlatformSection notSupported={["apple.ios", "apple.macos"]}>

```swift {tabTitle:Swift} {"onboardingOptions": {"performance": "13-16", "profiling": "17-21"}}
```swift {tabTitle:Swift}
import Sentry

func application(_ application: UIApplication,
Expand All @@ -186,21 +198,25 @@ func application(_ application: UIApplication,
// For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
options.sendDefaultPii = true

// ___PRODUCT_OPTION_START___ performance
// Set tracesSampleRate to 1 to capture 100% of transactions for performance monitoring.
// We recommend adjusting this value in production.
options.tracesSampleRate = 1
// ___PRODUCT_OPTION_END___ performance

// ___PRODUCT_OPTION_START___ profiling
options.configureProfiling = {
$0.lifecycle = .trace
$0.sessionSampleRate = 1
}
// ___PRODUCT_OPTION_END___ profiling
}

return true
}
```

```objc {tabTitle:Objective-C} {"onboardingOptions": {"performance": "12-15", "profiling": "16-20"}}
```objc {tabTitle:Objective-C}
@import Sentry;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
Expand All @@ -213,21 +229,25 @@ func application(_ application: UIApplication,
// For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
options.sendDefaultPii = YES

// ___PRODUCT_OPTION_START___ performance
// Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
// We recommend adjusting this value in production.
options.tracesSampleRate = @1.f;
// ___PRODUCT_OPTION_END___ performance

// ___PRODUCT_OPTION_START___ profiling
options.configureProfiling = ^(SentryProfileOptions *profiling) {
profiling.lifecycle = SentryProfileLifecycleTrace;
profiling.sessionSampleRate = 1.f;
};
// ___PRODUCT_OPTION_END___ profiling
}];

return YES;
}
```

```swift {tabTitle:SwiftUI with App conformer} {"onboardingOptions": {"performance": "13-16", "profiling": "17-21"}}
```swift {tabTitle:SwiftUI with App conformer}
import Sentry

@main
Expand All @@ -241,14 +261,18 @@ struct SwiftUIApp: App {
// For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
options.sendDefaultPii = true

// ___PRODUCT_OPTION_START___ performance
// Set tracesSampleRate to 1 to capture 100% of transactions for performance monitoring.
// We recommend adjusting this value in production.
options.tracesSampleRate = 1
// ___PRODUCT_OPTION_END___ performance

// ___PRODUCT_OPTION_START___ profiling
options.configureProfiling = {
$0.lifecycle = .trace
$0.sessionSampleRate = 1
}
// ___PRODUCT_OPTION_END___ profiling
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions docs/platforms/javascript/guides/hono/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ compatibility_flags = ["nodejs_als"]
Next, wrap your handler with the `withSentry` function. This will initialize the SDK and hook into the
environment. Note that you can turn off almost all side effects using the respective options.

```typescript {filename:index.ts} {"onboardingOptions": {"performance": "14-18"}}
```typescript {filename:index.ts}
import { Hono } from "hono";
import * as Sentry from "@sentry/cloudflare";

Expand All @@ -76,11 +76,13 @@ app.get("/", () => {
export default Sentry.withSentry(
(env) => ({
dsn: "___PUBLIC_DSN___",
// ___PRODUCT_OPTION_START___ performance

// Set tracesSampleRate to 1.0 to capture 100% of spans for tracing.
// Learn more at
// https://docs.sentry.io/platforms/javascript/configuration/options/#traces-sample-rate
tracesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ performance
}),
app
);
Expand Down Expand Up @@ -123,18 +125,20 @@ Next, add the `sentryPagesPlugin` as
We recommend adding a `functions/_middleware.js` for the middleware setup so that Sentry is initialized for your entire
app.

```javascript {filename:functions/_middleware.js} {"onboardingOptions": {"performance": "7-11"}}
```javascript {filename:functions/_middleware.js}
import * as Sentry from "@sentry/cloudflare";

export const onRequest = [
// Make sure Sentry is the first middleware
Sentry.sentryPagesPlugin((context) => ({
dsn: "___PUBLIC_DSN___",
// ___PRODUCT_OPTION_START___ performance

// Set tracesSampleRate to 1.0 to capture 100% of spans for tracing.
// Learn more at
// https://docs.sentry.io/platforms/javascript/configuration/options/#traces-sample-rate
tracesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ performance
})),
// Add more middlewares here
];
Expand Down
4 changes: 4 additions & 0 deletions src/components/docPage/type.scss
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@
[data-onboarding-option].hidden {
display: none;
}
// force hide markers (___PRODUCT_OPTION_START___ and ___PRODUCT_OPTION_END___)
[data-onboarding-option-hidden] {
display: none;
}
[data-onboarding-option].animate-line {
animation:
slideLeft 0.2s ease-out forwards,
Expand Down
4 changes: 4 additions & 0 deletions src/mdx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,10 @@ export async function getFileBySlug(slug: string) {

return options;
},
}).catch(e => {
// eslint-disable-next-line no-console
console.error('Error occurred during MDX compilation:', e.errors);
throw e;
});

const {code, frontmatter} = result;
Expand Down
58 changes: 48 additions & 10 deletions src/rehype-onboarding-lines.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @typedef {import('hast').Element} Element
* @typedef {import('hast').Root} Root
*/

import {toString} from 'hast-util-to-string';
import rangeParser from 'parse-numeric-range';
import {visit} from 'unist-util-visit';

Expand All @@ -25,6 +25,52 @@ export default function rehypeOnboardingLines() {
visit(tree, {type: 'element', tagName: 'code'}, visitor);
};
}

/**
* @param {Element} node
*/
function visitor(node) {
// ignore no code-highlight <code> tags as in in inline code resulting from a `markdown`
if (!node.properties.className?.includes('code-highlight')) {
return;
}

const meta = /** @type {string} */ (
node?.data?.meta || node?.properties?.metastring || ''
);

if (meta.includes('onboardingOptions')) {
handle_metadata_options(node, meta);
return;
}
handle_inline_options(node);
}

function handle_inline_options(node) {
/* @type {string | undefined} */
let currentOption;

// product options syntax
// ___PRODUCT_OPTION_START___ performance
// some lines here
// ___PRODUCT_OPTION_END___ performance
const PRODUCT_OPTION_START = '___PRODUCT_OPTION_START___';
const PRODUCT_OPTION_END = '___PRODUCT_OPTION_END___';
node.children?.forEach(line => {
const lineStr = toString(line);
if (lineStr.includes(PRODUCT_OPTION_START)) {
currentOption = lineStr.split(PRODUCT_OPTION_START)[1].trim();
line.properties['data-onboarding-option-hidden'] = '1';
} else if (lineStr.includes(PRODUCT_OPTION_END)) {
line.properties['data-onboarding-option-hidden'] = '1';
currentOption = undefined;
}
if (currentOption) {
line.properties['data-onboarding-option'] = currentOption;
}
});
}

/**
* Parse the line numbers from the metastring
* @param {string} meta
Expand Down Expand Up @@ -85,15 +131,7 @@ const getOptionForLine = meta => {
/**
* @param {Element} node
*/
function visitor(node) {
const meta = /** @type {string} */ (
node?.data?.meta || node?.properties?.metastring || ''
);

if (!meta.includes('onboardingOptions')) {
return;
}

function handle_metadata_options(node, meta) {
const optionForLine = getOptionForLine(meta);

node.children.forEach((line, index) => {
Expand Down
Loading