Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ed-codes
Created July 7, 2021 08:42
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ed-codes/5db385bef2a8ac7051d30d885e39b191 to your computer and use it in GitHub Desktop.
Save ed-codes/5db385bef2a8ac7051d30d885e39b191 to your computer and use it in GitHub Desktop.
Webflow 301 redirects bulk import
var hostingContainer = document.getElementsByClassName('hosting-tab')[0];
var hostingController = angular.element(hostingContainer);
var scope = hostingController.scope();
var redirects = [
{source: '/old1', target: '/new1'},
{source: '/old2', target: '/new2'},
];
redirects.forEach(function (rule) {
scope.redirectPath = rule.source;
scope.redirectTarget = rule.target;
scope.addRedirect();
});
@todd-g
Copy link

todd-g commented Aug 4, 2022

Webflow must have changed something, these aren't working anymore. It wants path and targetPath now - but I couldn't figure out how to send those properly. Just setting them on scope.path and scope.targetPath didn't work.

@HiagoSouz
Copy link

Webflow updated one class name. Code is outdated, but it's simple to fix.

In the line 1, instead of:
var hostingContainer = document.getElementsByClassName('hosting-tab')[0];

Use:
var hostingContainer = document.getElementsByClassName('publishing-tab')[0];

It will work now (Jan/23).

@jonnyread-ch
Copy link

Webflow changed their FE implementation again. Here's the updated code for it now:

// Define the redirect rules
let redirects = [
    {source: '/old1', target: '/new1'},
    {source: '/old2', target: '/new2'},
];
// Function to simulate a mouse click
function clickElement(element) {
    console.log(`Clicking on button: ${element.innerText}`); // Log the button click
    var event = new MouseEvent('click', {
        view: window,
        bubbles: true,
        cancelable: true
    });
    element.dispatchEvent(event);
}
// Function to set value to an input element
function setInputValue(inputElement, value) {
    console.log(`Setting value of ${inputElement.name} to ${value}`); // Log the value setting
    let lastValue = inputElement.value;
    inputElement.value = value;
    let event = new Event('input', { target: inputElement, bubbles: true });
    // Hack for react event
    event.simulated = true;
    let tracker = inputElement._valueTracker;
    if (tracker) {
        tracker.setValue(lastValue);
    }
    inputElement.dispatchEvent(event);
}
function findElByText(selector, text) {
    var elements = document.querySelectorAll(selector);
    return Array.prototype.find.call(elements, function(element){
        return RegExp(text).test(element.textContent);
    });
}
// Find the input fields and the add button
let oldPathInput = document.querySelector('input[name="path"]');
let newPathInput = document.querySelector('input[name="targetPath"]');
let addButton = findElByText('button', 'Add redirect path');
// For each redirect rule, fill the form and click the add button
if (!addButton) {
    alert('Could not find the add button');
} else {
    redirects.forEach((rule) => {
        console.log(`Processing rule: ${JSON.stringify(rule)}`); // Log the current rule
        setInputValue(oldPathInput, rule.source);
        setInputValue(newPathInput, rule.target);
        clickElement(addButton);
    });
}

@QuentinGW
Copy link

@jonnyread-ch Thanks a lot. It works perfectly

@brandonmlyon
Copy link

brandonmlyon commented Dec 1, 2023

This worked too well 😆

It appears that it's possible to bring down a site because this can bypass Webflow's error checks. Don't attempt to add redirects with any non-latin characters like nor special characters like ;

@laurent-by-o
Copy link

It seems like something recently changed on webflow's interface. The loop works but only the first redirect entry is actually submitted.

@bearstar
Copy link

Same experience as Laurent-by-o. The first redirect processes and the rest are ignored.

@laurent-by-o
Copy link

laurent-by-o commented Mar 13, 2024

@bearstar this solved it for me:

let redirects = [
{source: '/old1', target: '/new1'},
{source: '/old2', target: '/new2'},
];

function clickElement(element) {
console.log(Clicking on button: ${element.innerText});
var event = new MouseEvent('click', { view: window, bubbles: true, cancelable: true });
element.dispatchEvent(event);
}

function setInputValue(inputElement, value) {
console.log(Setting value of ${inputElement.name} to ${value});
let lastValue = inputElement.value;
inputElement.value = value;
let event = new Event('input', { target: inputElement, bubbles: true });
event.simulated = true;
let tracker = inputElement._valueTracker;
if (tracker) { tracker.setValue(lastValue); }
inputElement.dispatchEvent(event);
}

function findElByText(selector, text) {
var elements = document.querySelectorAll(selector);
return Array.prototype.find.call(elements, function(element){
return RegExp(text).test(element.textContent);
});
}

async function processRedirects(redirects) {
for (let rule of redirects) {
console.log(Processing rule: ${JSON.stringify(rule)});

    let oldPathInput = document.querySelector('input[name="path"]');
    let newPathInput = document.querySelector('input[name="targetPath"]');
    let addButton = findElByText('button', 'Add redirect path');

    if (!addButton) {
        alert('Could not find the add button');
        break; // Exit if the add button can't be found
    } else {
        setInputValue(oldPathInput, rule.source);
        setInputValue(newPathInput, rule.target);
        clickElement(addButton);
        
        // Wait for a short delay to allow the DOM to update
        await new Promise(resolve => setTimeout(resolve, 1000));
    }
}

}

// Start processing the redirects
processRedirects(redirects);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment