or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configurations.mdconvention-rules.mddocument-rules.mdindex.mdperformance-rules.mdscript-rules.md

script-rules.mddocs/

0

# Script & Asset Management Rules

1

2

ESLint rules for proper script loading and asset management in Next.js applications. These rules ensure optimal script placement, loading strategies, and prevent common script-related performance issues.

3

4

## Capabilities

5

6

### inline-script-id

7

8

Enforces id attribute for inline scripts to enable proper CSP and security practices.

9

10

```typescript { .api }

11

/**

12

* Rule: inline-script-id

13

* Enforces id attribute for inline scripts

14

* Severity: error (in recommended config)

15

* Category: Security/Scripts

16

*/

17

interface InlineScriptIdRule extends Rule.RuleModule {

18

meta: {

19

docs: {

20

description: 'Enforce id attribute for inline scripts';

21

category: 'Security';

22

recommended: true;

23

url: string;

24

};

25

type: 'problem';

26

schema: [];

27

};

28

}

29

```

30

31

**Validates:** Inline script elements have id attributes

32

**Prevents:** CSP violations and security issues with inline scripts

33

34

### next-script-for-ga

35

36

Enforces Next.js Script component for Google Analytics instead of HTML script tags.

37

38

```typescript { .api }

39

/**

40

* Rule: next-script-for-ga

41

* Enforces Next.js Script component for Google Analytics

42

* Severity: warn (in recommended config)

43

* Category: Performance/Scripts

44

*/

45

interface NextScriptForGARule extends Rule.RuleModule {

46

meta: {

47

docs: {

48

description: 'Enforce Next.js Script component for Google Analytics';

49

category: 'Performance';

50

recommended: true;

51

url: string;

52

};

53

type: 'suggestion';

54

schema: [];

55

};

56

}

57

```

58

59

**Validates:** Google Analytics uses Next.js Script component

60

**Prevents:** Suboptimal loading strategies for analytics scripts

61

62

### no-before-interactive-script-outside-document

63

64

Prevents beforeInteractive scripts outside of _document.js where they won't work correctly.

65

66

```typescript { .api }

67

/**

68

* Rule: no-before-interactive-script-outside-document

69

* Prevents beforeInteractive scripts outside _document.js

70

* Severity: warn (in recommended config)

71

* Category: Scripts/Architecture

72

*/

73

interface NoBeforeInteractiveScriptOutsideDocumentRule extends Rule.RuleModule {

74

meta: {

75

docs: {

76

description: 'Prevent beforeInteractive scripts outside _document.js';

77

category: 'Architecture';

78

recommended: true;

79

url: string;

80

};

81

type: 'problem';

82

schema: [];

83

};

84

}

85

```

86

87

**Validates:** beforeInteractive scripts are only in _document.js

88

**Prevents:** Scripts that won't load with correct timing strategy

89

90

### no-script-component-in-head

91

92

Prevents Script components inside Head components where they're ineffective.

93

94

```typescript { .api }

95

/**

96

* Rule: no-script-component-in-head

97

* Prevents Script components in Head components

98

* Severity: error (in recommended config)

99

* Category: Scripts/Architecture

100

*/

101

interface NoScriptComponentInHeadRule extends Rule.RuleModule {

102

meta: {

103

docs: {

104

description: 'Prevent Script components in Head';

105

category: 'Architecture';

106

recommended: true;

107

url: string;

108

};

109

type: 'problem';

110

schema: [];

111

};

112

}

113

```

114

115

**Validates:** Script components are not placed inside Head components

116

**Prevents:** Scripts that won't execute due to incorrect placement

117

118

### no-unwanted-polyfillio

119

120

Prevents unwanted polyfill.io usage that can introduce security and performance issues.

121

122

```typescript { .api }

123

/**

124

* Rule: no-unwanted-polyfillio

125

* Prevents unwanted polyfill.io usage

126

* Severity: warn (in recommended config)

127

* Category: Security/Performance

128

*/

129

interface NoUnwantedPolyfillIoRule extends Rule.RuleModule {

130

meta: {

131

docs: {

132

description: 'Prevent unwanted polyfill.io usage';

133

category: 'Security';

134

recommended: true;

135

url: string;

136

};

137

type: 'problem';

138

schema: [];

139

};

140

}

141

```

142

143

**Validates:** Polyfill.io scripts are not used without justification

144

**Prevents:** Potential security and performance issues from third-party polyfills

145

146

### no-css-tags

147

148

Prevents manual CSS link tags in favor of Next.js CSS import system.

149

150

```typescript { .api }

151

/**

152

* Rule: no-css-tags

153

* Prevents manual CSS link tags

154

* Severity: warn (in recommended config)

155

* Category: Assets/Performance

156

*/

157

interface NoCssTagsRule extends Rule.RuleModule {

158

meta: {

159

docs: {

160

description: 'Prevent manual CSS link tags';

161

category: 'Performance';

162

recommended: true;

163

url: string;

164

};

165

type: 'suggestion';

166

schema: [];

167

};

168

}

169

```

170

171

**Validates:** CSS is loaded through Next.js import system

172

**Prevents:** Suboptimal CSS loading and missing optimizations

173

174

## Usage Examples

175

176

### Correct Script Usage

177

178

```jsx

179

// ✅ Correct - Using Next.js Script component

180

import Script from 'next/script';

181

182

export default function MyPage() {

183

return (

184

<>

185

<div>Page content</div>

186

187

{/* Google Analytics with Next.js Script */}

188

<Script

189

src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"

190

strategy="afterInteractive"

191

/>

192

<Script id="google-analytics" strategy="afterInteractive">

193

{`

194

window.dataLayer = window.dataLayer || [];

195

function gtag(){dataLayer.push(arguments);}

196

gtag('js', new Date());

197

gtag('config', 'GA_MEASUREMENT_ID');

198

`}

199

</Script>

200

</>

201

);

202

}

203

```

204

205

### Correct Document Scripts

206

207

```jsx

208

// ✅ Correct - beforeInteractive scripts in _document.js

209

import { Html, Head, Main, NextScript } from 'next/document';

210

import Script from 'next/script';

211

212

export default function Document() {

213

return (

214

<Html>

215

<Head />

216

<body>

217

<Main />

218

<NextScript />

219

220

{/* Critical scripts that need to load before interactivity */}

221

<Script

222

id="critical-script"

223

strategy="beforeInteractive"

224

src="/critical-script.js"

225

/>

226

</body>

227

</Html>

228

);

229

}

230

```

231

232

### Correct CSS Loading

233

234

```jsx

235

// ✅ Correct - CSS through Next.js import system

236

import styles from './MyComponent.module.css';

237

import 'global-styles.css';

238

239

export default function MyComponent() {

240

return <div className={styles.container}>Content</div>;

241

}

242

```

243

244

### Script Rules Configuration

245

246

```javascript

247

// Focus on script management and security

248

module.exports = {

249

plugins: ['@next/next'],

250

rules: {

251

// Critical script placement rules as errors

252

'@next/next/inline-script-id': 'error',

253

'@next/next/no-script-component-in-head': 'error',

254

255

// Best practice rules as warnings

256

'@next/next/next-script-for-ga': 'warn',

257

'@next/next/no-before-interactive-script-outside-document': 'warn',

258

'@next/next/no-unwanted-polyfillio': 'warn',

259

'@next/next/no-css-tags': 'warn',

260

},

261

};

262

```

263

264

## Script Loading Strategies

265

266

### Available Strategies

267

- **beforeInteractive**: Load before page becomes interactive (only in _document.js)

268

- **afterInteractive**: Load after page becomes interactive

269

- **lazyOnload**: Load during browser idle time

270

- **worker**: Load in a web worker (experimental)

271

272

### Strategy Guidelines

273

- Use `beforeInteractive` for critical scripts that must load early

274

- Use `afterInteractive` for analytics and non-critical functionality

275

- Use `lazyOnload` for scripts that can be deferred

276

- Always specify a strategy explicitly

277

278

## Rule Categories

279

280

- **Security**: inline-script-id, no-unwanted-polyfillio

281

- **Performance**: next-script-for-ga, no-css-tags

282

- **Architecture**: no-before-interactive-script-outside-document, no-script-component-in-head

283

284

## Common Patterns

285

286

### Analytics Integration

287

- Use Next.js Script component with proper strategy

288

- Include required id attributes for inline scripts

289

- Place analytics scripts at page level, not in _document

290

291

### Critical Script Loading

292

- Place beforeInteractive scripts only in _document.js

293

- Use afterInteractive for most third-party scripts

294

- Avoid placing scripts inside Head components

295

296

### Asset Management

297

- Use Next.js CSS import system instead of link tags

298

- Leverage automatic optimization and bundling

299

- Maintain proper loading order and dependencies