or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-postcss-normalize-url

Normalize URLs with PostCSS

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/postcss-normalize-url@7.0.x

To install, run

npx @tessl/cli install tessl/npm-postcss-normalize-url@7.0.0

0

# PostCSS Normalize URL

1

2

PostCSS Normalize URL is a PostCSS plugin that normalizes URLs within CSS stylesheets. It automatically optimizes URL formats for better compression and standardization by removing unnecessary port numbers, converting absolute URLs to more efficient formats, normalizing relative paths, and intelligently managing quotes around URLs.

3

4

## Package Information

5

6

- **Package Name**: postcss-normalize-url

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install postcss-normalize-url`

10

11

## Core Imports

12

13

```javascript

14

const postcssNormalizeUrl = require("postcss-normalize-url");

15

```

16

17

ES modules:

18

19

```javascript

20

import postcssNormalizeUrl from "postcss-normalize-url";

21

```

22

23

24

## Basic Usage

25

26

```javascript

27

const postcss = require("postcss");

28

const postcssNormalizeUrl = require("postcss-normalize-url");

29

30

// Use as PostCSS plugin

31

const result = await postcss([postcssNormalizeUrl()])

32

.process("h1 { background: url(\"http://site.com:80/image.jpg\") }", {

33

from: undefined

34

});

35

36

console.log(result.css);

37

// Output: h1 { background: url(http://site.com/image.jpg) }

38

```

39

40

41

## Capabilities

42

43

### PostCSS Plugin Creator

44

45

Creates a PostCSS plugin instance for URL normalization in CSS.

46

47

```javascript { .api }

48

/**

49

* Creates a PostCSS plugin that normalizes URLs in CSS

50

* @returns {Plugin} PostCSS plugin object with postcss property

51

*/

52

function postcssNormalizeUrl(): Plugin;

53

54

// Plugin properties

55

postcssNormalizeUrl.postcss = true;

56

```

57

58

The plugin processes CSS and performs the following normalizations:

59

60

- **Port Removal**: Removes default ports (`:80` for HTTP, `:443` for HTTPS)

61

- **Quote Optimization**: Removes unnecessary quotes around URLs, adds escaping when needed

62

- **Path Normalization**: Normalizes relative paths using Node.js path.normalize and resolves directory traversals (`../`)

63

- **Protocol Handling**: Processes absolute URLs and protocol-relative URLs

64

- **Whitespace Handling**: Removes unnecessary whitespace inside URL functions and strings

65

- **Multiline Support**: Joins multiline URL strings that use backslash continuation

66

- **Special URL Preservation**: Leaves data URLs and browser extension URLs unchanged

67

- **Fragment Preservation**: Maintains URL fragments (hash portions) in both relative and absolute URLs

68

69

### @namespace Rule Processing

70

71

Processes CSS @namespace rules and normalizes URLs within them.

72

73

```javascript { .api }

74

// Plugin automatically handles @namespace rules

75

// Input: @namespace url("http://example.com:80/ns");

76

// Output: @namespace url(http://example.com/ns);

77

```

78

79

The plugin specifically processes:

80

- **@namespace Rules**: Converts url() functions to strings and normalizes them

81

- **Function to String Conversion**: Transforms url() functions to quoted strings in namespace contexts

82

- **Quote Management**: Preserves or adds appropriate quotes as needed

83

84

## Types

85

86

```typescript { .api }

87

interface Plugin {

88

postcssPlugin: 'postcss-normalize-url';

89

OnceExit(css: Root): void;

90

}

91

92

// Plugin creator function with postcss property

93

interface PluginCreator {

94

(): Plugin;

95

postcss: true;

96

}

97

98

// PostCSS types (from postcss package)

99

interface Root {

100

walk(callback: (node: Node) => boolean | void): Root;

101

}

102

103

interface Node {

104

type: string;

105

}

106

107

interface Declaration extends Node {

108

type: 'decl';

109

value: string;

110

}

111

112

interface AtRule extends Node {

113

type: 'atrule';

114

name: string;

115

params: string;

116

}

117

```

118

119

## Error Handling

120

121

The plugin includes robust error handling:

122

123

- **Malformed URLs**: Invalid URLs are left unchanged rather than breaking the build

124

- **Data URL Parsing**: Invalid data URLs fall back to the original value

125

- **Path Normalization**: Errors in path processing don't interrupt CSS processing

126

- **Extension URLs**: Browser extension URLs (e.g., `chrome-extension://`) are preserved unchanged

127

128

## URL Processing Examples

129

130

### Default Port Removal

131

```css

132

/* Input */

133

h1 { background: url("http://site.com:80/image.jpg") }

134

135

/* Output */

136

h1 { background: url(http://site.com/image.jpg) }

137

```

138

139

### Quote Optimization

140

```css

141

/* Input */

142

h1 { background: url("simple-image.jpg") }

143

144

/* Output */

145

h1 { background: url(simple-image.jpg) }

146

```

147

148

### Special Character Escaping

149

```css

150

/* Input */

151

h1 { background: url("path with spaces.jpg") }

152

153

/* Output */

154

h1 { background: url("path with spaces.jpg") }

155

```

156

157

### Relative Path Normalization

158

```css

159

/* Input */

160

h1 { background: url("./images/../icons/icon.png") }

161

162

/* Output */

163

h1 { background: url(icons/icon.png) }

164

```

165

166

### Directory Traversal Resolution

167

```css

168

/* Input */

169

h1 { background: url("css/../font/t.eot") }

170

171

/* Output */

172

h1 { background: url(font/t.eot) }

173

```

174

175

### Whitespace Normalization

176

```css

177

/* Input */

178

h1 { background: url(" test.png ") }

179

180

/* Output */

181

h1 { background: url(test.png) }

182

```

183

184

### Multiline URL Handling

185

```css

186

/* Input */

187

h1 { background: url("some really long string \

188

spanning multiple lines") }

189

190

/* Output */

191

h1 { background: url("some really long string spanning multiple lines") }

192

```

193

194

### Fragment Preservation

195

```css

196

/* Input */

197

h1 { background: url("http://website.com/test.svg#icon") }

198

199

/* Output - fragment preserved */

200

h1 { background: url(http://website.com/test.svg#icon) }

201

```

202

203

### Data URL Preservation

204

```css

205

/* Input */

206

h1 { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==") }

207

208

/* Output - preserved unchanged */

209

h1 { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==") }

210

```