diff --git a/packages/react-native-babel-plugin/src/actions/rum/index.ts b/packages/react-native-babel-plugin/src/actions/rum/index.ts
index 7454ef0dc..8c170fc21 100644
--- a/packages/react-native-babel-plugin/src/actions/rum/index.ts
+++ b/packages/react-native-babel-plugin/src/actions/rum/index.ts
@@ -247,9 +247,12 @@ function jsxChildToRuntimeCall(
t.isJSXAttribute(attr)
)
.map(attr => {
- const key = t.isJSXIdentifier(attr.name)
- ? t.identifier(attr.name.name)
- : t.stringLiteral(getNodeName(t, attr.name) || '');
+ const key =
+ t.isJSXIdentifier(attr.name) &&
+ t.isValidIdentifier(attr.name.name)
+ ? t.identifier(attr.name.name)
+ : t.stringLiteral(getNodeName(t, attr.name) || '');
+
let value: Babel.types.Expression;
if (!attr.value) {
value = t.booleanLiteral(true);
diff --git a/packages/react-native-babel-plugin/test/plugin.test.ts b/packages/react-native-babel-plugin/test/plugin.test.ts
index 657f8bbb5..c9bf29d8c 100644
--- a/packages/react-native-babel-plugin/test/plugin.test.ts
+++ b/packages/react-native-babel-plugin/test/plugin.test.ts
@@ -1644,3 +1644,86 @@ describe('Babel plugin: wrap interaction handlers for RUM ( with memoization )',
`);
});
});
+
+describe('Babel plugin: hyphenated JSX attribute names in getContent', () => {
+ function extractGetContent(output: string | null | undefined): string {
+ if (!output) {
+ return '';
+ }
+ const match = output.match(
+ /"getContent"\s*:\s*\(\)\s*=>\s*\{[\s\S]*?return\s+([\s\S]*?);\s*\}/
+ );
+ return match ? match[1] : '';
+ }
+
+ it('should quote hyphenated attribute names in getContent child elements to produce valid JS', () => {
+ const input = `
+ import { TouchableOpacity, View, Text } from 'react-native';
+
+ function MyComponent() {
+ return (
+ {}}>
+
+ Hello
+
+
+ );
+ }
+ `;
+
+ const output = transformCode(input);
+ const getContent = extractGetContent(output);
+ // Inside getContent, the generated _jsx call must use "aria-hidden" (quoted string)
+ // not aria-hidden (bare identifier) because aria-hidden is not a valid JS identifier.
+ // Bare identifiers with hyphens cause Hermes parse errors: ':' expected in property initialization
+ expect(getContent).toContain('"aria-hidden"');
+ expect(getContent).not.toMatch(/\baria-hidden\b(?!":)/);
+ });
+
+ it('should quote multiple hyphenated attribute names in getContent child elements', () => {
+ const input = `
+ import { TouchableOpacity, View, Text } from 'react-native';
+
+ function MyComponent() {
+ return (
+ {}}>
+
+ Hello
+
+
+ );
+ }
+ `;
+
+ const output = transformCode(input);
+ const getContent = extractGetContent(output);
+ expect(getContent).toContain('"aria-hidden"');
+ expect(getContent).toContain('"aria-label"');
+ expect(getContent).toContain('"data-testid"');
+ });
+
+ it('should not quote valid JS identifier attribute names in getContent child elements', () => {
+ const input = `
+ import { TouchableOpacity, View, Text } from 'react-native';
+
+ function MyComponent() {
+ return (
+ {}}>
+
+ Hello
+
+
+ );
+ }
+ `;
+
+ const output = transformCode(input);
+ const getContent = extractGetContent(output);
+ // Valid JS identifiers like "style" and "accessible" should remain bare (unquoted)
+ expect(getContent).toMatch(/\bstyle:/);
+ expect(getContent).toMatch(/\baccessible:/);
+ // They should NOT be quoted as string literals
+ expect(getContent).not.toContain('"style"');
+ expect(getContent).not.toContain('"accessible"');
+ });
+});