Skip to main content

Webchat Responsive Positioning

The Filum Chat SDK allows you to customize the chat widget's position based on viewport dimensions using the responsivePositions configuration option. This feature enables you to define rules that automatically adjust the chat widget's position when specific viewport conditions are met.

How Responsive Positioning Works

By default, the chat widget is positioned:

  • 10px from the bottom edge
  • 10px from the right edge

You can override these defaults using positionBottom and positionRight. For more advanced control, use responsivePositions to define conditional positioning rules based on viewport width and height.

Key Concepts

  • Conditions: Each rule specifies viewport width/height requirements
  • All conditions must match: Within a rule, all specified conditions use AND logic
  • Inclusive ranges: Min/max values are inclusive (uses >= and <=)
  • Last match wins: If multiple rules match, the last matching rule takes precedence
  • Automatic updates: Position recalculates automatically when the window resizes
  • Fallback behavior: If no rules match, falls back to positionBottom and positionRight defaults

Basic Usage

window.filumChat.initialize({
organizationId: 'your-organization-id',
installedSourceId: 123,

// Default position (used when no responsive rules match)
positionBottom: 10,
positionRight: 10,

// Responsive positioning rules
responsivePositions: [
{
// On mobile screens (width ≤ 768px)
conditions: {
width: { max: 768 }
},
positionBottom: 0,
positionRight: 0
}
]
})

Configuration API

responsivePositions Array

An array of positioning rules. Each rule is an object with the following structure:

type ResponsivePosition = {
conditions: {
width?: {
min?: number // Minimum viewport width (inclusive, >=)
max?: number // Maximum viewport width (inclusive, <=)
}
height?: {
min?: number // Minimum viewport height (inclusive, >=)
max?: number // Maximum viewport height (inclusive, <=)
}
}
positionBottom?: string | number // Bottom position override
positionRight?: string | number // Right position override
}

Examples

Example 1: Mobile-First Positioning

Position the chat differently on mobile vs desktop:

window.filumChat.initialize({
organizationId: 'your-organization-id',
installedSourceId: 123,

// Desktop default
positionBottom: 20,
positionRight: 20,

responsivePositions: [
{
// Mobile: full edge alignment
conditions: {
width: { max: 768 }
},
positionBottom: 0,
positionRight: 0
}
]
})

Example 2: Multiple Breakpoints

Define different positions for mobile, tablet, and desktop:

window.filumChat.initialize({
organizationId: 'your-organization-id',
installedSourceId: 123,

// Default (desktop)
positionBottom: 24,
positionRight: 24,

responsivePositions: [
{
// Mobile (0-480px)
conditions: {
width: { max: 480 }
},
positionBottom: 0,
positionRight: 0
},
{
// Tablet (481-1024px)
conditions: {
width: { min: 481, max: 1024 }
},
positionBottom: 16,
positionRight: 16
}
]
})

Example 3: Avoiding Fixed Bottom Navigation

Position the chat above a fixed navigation bar on smaller screens:

window.filumChat.initialize({
organizationId: 'your-organization-id',
installedSourceId: 123,

positionBottom: 20,
positionRight: 20,

responsivePositions: [
{
// On mobile with bottom nav (60px height)
conditions: {
width: { max: 768 }
},
positionBottom: 70, // 60px nav + 10px gap
positionRight: 10
}
]
})

Example 4: Height-Based Positioning

Adjust position based on viewport height (useful for landscape mobile):

window.filumChat.initialize({
organizationId: 'your-organization-id',
installedSourceId: 123,

positionBottom: 20,
positionRight: 20,

responsivePositions: [
{
// Short viewports (landscape mobile)
conditions: {
height: { max: 500 }
},
positionBottom: 10,
positionRight: 10
}
]
})

Example 5: Combined Width and Height Conditions

Use both width AND height conditions for precise targeting:

window.filumChat.initialize({
organizationId: 'your-organization-id',
installedSourceId: 123,

positionBottom: 20,
positionRight: 20,

responsivePositions: [
{
// Small screens in landscape mode
conditions: {
width: { max: 768 },
height: { max: 500 }
},
positionBottom: 5,
positionRight: 5
}
]
})

Example 6: Using CSS Units

Position values can use any CSS unit:

window.filumChat.initialize({
organizationId: 'your-organization-id',
installedSourceId: 123,

positionBottom: "2rem",
positionRight: "2rem",

responsivePositions: [
{
conditions: {
width: { max: 768 }
},
positionBottom: "1rem",
positionRight: "1rem"
},
{
conditions: {
width: { max: 480 }
},
positionBottom: "5%",
positionRight: "5%"
}
]
})

Understanding Rule Matching

Inclusive Ranges

Min and max values are inclusive, meaning they use >= and <= operators:

// Rule with width: { min: 480, max: 768 }
// Matches: 480px, 481px, 482px, ..., 767px, 768px

Last Match Wins

When multiple rules match the current viewport, the last matching rule takes precedence:

window.filumChat.initialize({
organizationId: 'your-organization-id',
installedSourceId: 123,

positionBottom: 20,

responsivePositions: [
{
conditions: { width: { max: 768 } },
positionBottom: 10 // Matches at 768px
},
{
conditions: { width: { max: 1024 } },
positionBottom: 15 // Also matches at 768px → WINS
}
]
})

// At viewport width = 768px
// Both rules match, but the second rule wins
// Result: positionBottom = 15

All Conditions Must Match (AND Logic)

Within a single rule, all specified conditions must match:

{
conditions: {
width: { min: 768, max: 1024 },
height: { min: 600 }
},
positionBottom: 30
}

// This rule only applies when:
// - Viewport width is between 768px and 1024px (inclusive) AND
// - Viewport height is at least 600px

Partial Condition Specifications

You can specify only min, only max, or both:

responsivePositions: [
{
// Matches all viewports ≥ 1200px wide
conditions: {
width: { min: 1200 }
},
positionRight: 40
},
{
// Matches all viewports ≤ 480px wide
conditions: {
width: { max: 480 }
},
positionRight: 0
},
{
// Matches viewports between 768px and 1024px wide
conditions: {
width: { min: 768, max: 1024 }
},
positionRight: 20
}
]

Important Notes

info

The responsivePositions feature is opt-in. The chat widget does not automatically adapt its position unless you explicitly configure responsive rules. Without responsivePositions, the chat uses the default positionBottom and positionRight values (or their defaults of 10px).

info

When the chat enters mobile full-screen mode (determined by the chat's internal responsive breakpoints), all positioning values are automatically overridden to 0px to provide a full-screen experience. The responsivePositions rules only apply when the chat is in normal (non-full-screen) mode.

caution

The responsivePositions property must be an array. If you provide a non-array value, the SDK will log a warning and ignore the invalid configuration.

caution

Empty arrays are valid but have no effect. The chat will fall back to default positioning:

// These are functionally equivalent:
responsivePositions: []
// vs.
// (no responsivePositions property)

Best Practices

1. Define Defaults First

Always set positionBottom and positionRight as fallback values:

window.filumChat.initialize({
organizationId: 'your-organization-id',
installedSourceId: 123,

// Fallback defaults
positionBottom: 20,
positionRight: 20,

// Responsive overrides
responsivePositions: [
// ... rules
]
})

2. Order Rules from Specific to General

Place more specific rules first, and more general rules last:

responsivePositions: [
{
// Very specific: landscape mobile
conditions: {
width: { max: 768 },
height: { max: 500 }
},
positionBottom: 5
},
{
// More general: all mobile
conditions: {
width: { max: 768 }
},
positionBottom: 10
}
]

3. Test Across Breakpoints

Test your configuration at common viewport sizes:

  • Mobile: 375px, 414px, 480px
  • Tablet: 768px, 1024px
  • Desktop: 1280px, 1440px, 1920px

4. Use Consistent Units

For easier maintenance, use consistent units across your rules:

// Good: consistent rem units
positionBottom: "1.5rem",
positionRight: "1.5rem",
responsivePositions: [
{
conditions: { width: { max: 768 } },
positionBottom: "1rem",
positionRight: "1rem"
}
]

5. Consider Orientation Changes

Mobile devices change dimensions when rotated. Test both portrait and landscape:

responsivePositions: [
{
// Portrait mobile
conditions: {
width: { max: 480 },
height: { min: 600 }
},
positionBottom: 10
},
{
// Landscape mobile
conditions: {
width: { max: 768 },
height: { max: 500 }
},
positionBottom: 5
}
]

Combining with Other Options

The responsivePositions feature works seamlessly with other configuration options:

window.filumChat.initialize({
organizationId: 'your-organization-id',
installedSourceId: 123,

// Positioning
positionBottom: 20,
positionRight: 20,
responsivePositions: [
{
conditions: { width: { max: 768 } },
positionBottom: 0,
positionRight: 0
}
],

// Other options
zIndex: 9998,
hideLauncherButton: false,
openAfterAttached: false,

onOpenChange: (open) => {
console.log(`Chat is ${open ? 'open' : 'closed'}`)
}
})

TypeScript Support

The responsive positioning API is fully typed:

interface ResponsivePosition {
conditions: {
width?: {
min?: number
max?: number
}
height?: {
min?: number
max?: number
}
}
positionBottom?: string | number
positionRight?: string | number
}

interface AttachConfig {
organizationId: string
installedSourceId: number
positionRight?: string | number
positionBottom?: string | number
responsivePositions?: ResponsivePosition[]
// ... other options
}

Troubleshooting

Rules Not Applying

If your responsive rules aren't working:

  1. Check the browser console for validation warnings
  2. Verify responsivePositions is an array: responsivePositions: [...] not responsivePositions: {...}
  3. Test your conditions: Use browser DevTools to check actual viewport dimensions
  4. Remember last match wins: Later rules override earlier ones
  5. Check full-screen mode: Rules don't apply when chat is in mobile full-screen mode

Position Jumps on Resize

If you experience position jumps when resizing:

  1. Check for overlapping rules with different position values
  2. Consider using smoother breakpoints to minimize visual jumps
  3. Use relative units (rem, %) for smoother transitions

Debugging Example

Add console logging to understand which rules are matching:

const config = {
organizationId: 'your-organization-id',
installedSourceId: 123,

positionBottom: 20,
positionRight: 20,

responsivePositions: [
{
conditions: { width: { max: 768 } },
positionBottom: 0,
positionRight: 0
}
]
}

console.log('Current viewport:', window.innerWidth, 'x', window.innerHeight)
console.log('Config:', config)

window.filumChat.initialize(config)

Browser Compatibility

The responsive positioning feature works across all modern browsers that support:

  • Window resize events
  • window.innerWidth and window.innerHeight
  • CSS fixed positioning
  • Dynamic CSS property updates

This includes all versions of Chrome, Firefox, Safari, and Edge from the past 5 years.